From 905bf22e0c8461a340b7bd204e6982f785398922 Mon Sep 17 00:00:00 2001 From: Jessica Borja Date: Wed, 17 Feb 2021 18:12:56 +0100 Subject: [PATCH 01/22] BOHB output and CAVE analysis --- .gitignore | 4 + config_readme.md | 96 +- experiments/dqn_vanilla_hps.py | 12 +- ..._representations_tune_hps_cave_analysis.py | 151 + mdp_playground/analysis/analysis.py | 37 +- mdp_playground/analysis/mdpp_to_cave.py | 232 ++ plot_experiments.ipynb | 3581 ++++++++++++++++- run_experiments.py | 4 + 8 files changed, 4096 insertions(+), 21 deletions(-) create mode 100644 experiments/rainbow_image_representations_tune_hps_cave_analysis.py create mode 100644 mdp_playground/analysis/mdpp_to_cave.py diff --git a/.gitignore b/.gitignore index 76aa8b6..e5e4f1c 100644 --- a/.gitignore +++ b/.gitignore @@ -106,3 +106,7 @@ venv.bak/ # mypy .mypy_cache/ + +.vscode/ +*.pdf +..mdpp_to_cave/dqn_seq_del/output/.OLD.zip diff --git a/config_readme.md b/config_readme.md index 04f2031..55e020b 100644 --- a/config_readme.md +++ b/config_readme.md @@ -66,4 +66,98 @@ Please look into the code for details. eyJoaXN0b3J5IjpbMTIwMDgzNDAyMCw5ODA0NTQ0ODcsMTE0MD A3ODc3NCwtMTQyODk4MjI4LC0xNzIzNDk4MDQwLDEwNTIzNjcx OV19 ---> \ No newline at end of file +--> + +## API for agents +If you implement an agent and want to use our run_experiments.py out of the box then agent must follow the following API: +1. It should have a config that can be passed as dictionary +2. The configuration values of the **agent** should be specified as follows: + +### Exploration +* **schedule_max_timesteps (int):** +Max num timesteps for annealing schedules. Exploration is annealed from 1.0 to exploration_fraction over this number of timesteps scaled by exploration_fraction + +* **timesteps_per_iteration (int):** +Number of env steps to optimize for before returning + +* **exploration_fraction (float):** +Fraction of entire training period over which the exploration rate is annealed + +* **exploration_final_eps (float):** +Final value of random action probability + +* **target_network_update_freq (int):** +Update the target network every `target_network_update_freq` steps. + + +### Replay buffer configuration +* **buffer_size (int):** +Size of the replay buffer. + +* **prioritized_replay (bool):** +If True prioritized replay buffer will be used + +* **prioritized_replay_alpha (float):** +Alpha parameter for prioritized replay buffer + +* **prioritized_replay_beta (float):** +Beta parameter for sampling from prioritized replay buffer. + +* **beta_annealing_fraction (float):** +Fraction of entire training period over which the beta parameter is annealed. + +* **final_prioritized_replay_beta (float):** +Final value of beta + +* **prioritized_replay_eps (float):** +Epsilon to add to the TD errors when updating priorities. + +### Optimization: +* **lr (float):** +Learning rate for adam optimizer + +* **adam_epsilon (float):** +Adam epsilon hyper parameter + +* **grad_norm_clipping (float):** +If not None, clip gradients during optimization at this value. + +* **learning_starts (int):** +How many steps of the model to sample before learning starts. + +* **train_batch_size (int):** +Size of a batched sampled from replay buffer for training. Note that if async_updates is set, then each worker returns gradients for a batch of this size. + +### Execution: +* **num_envs_per_worker (int):** +Number of environments to evaluate vectorwise per worker. + +* **sample_batch_size (int):** +Default sample batch size (unroll length). Batches of this size are collected from workers until train_batch_size is met. When using multiple envs per worker, this is multiplied by num_envs_per_worker. The replay buffer is updated with this many samples at once. Note that this setting applies per-worker if num_workers > 1. + +* **train_batch_size (int):** +Size of a batched sampled from replay buffer for training. Note that if async_updates is set, then each worker returns gradients for a batch of this size. +Should be >= sample_batch_size. Samples batches will be concatenated together to this size for training. + + * **batch_mode (str):** +Whether to rollout "complete_episodes" or "truncate_episodes". + + * **sample_async (bool):** +Use a background thread for sampling (slightly off-policy) + +### DQN specifics: +* **noisy (bool):** +Whether to use noisy network + +* **dueling (bool):** +Whether to use dueling dqn + +* **double_q (bool):** +Whether to use double dqn + +* **hiddens ( [int] vector):** +Postprocess model outputs with these hidden layers to compute the state and action values. + +* **n_step (int):** +N-step Q learning + \ No newline at end of file diff --git a/experiments/dqn_vanilla_hps.py b/experiments/dqn_vanilla_hps.py index bb1446b..c201410 100644 --- a/experiments/dqn_vanilla_hps.py +++ b/experiments/dqn_vanilla_hps.py @@ -15,9 +15,9 @@ var_agent_configs = OrderedDict({ # normalise obs./reward, atari preprocessing - 'learning_starts' : [200, 500, 1000, 5000, 10000] - #'target_network_update_freq': [200, 400, 800, 1600, 3200] - #'train_batch_size': [4, 8, 16, 32, 64, 128], + #'learning_starts' : [10, 200, 500, 1000, 5000, 10000] + #'target_network_update_freq': [1, 2, 4, 8, 16, 32, 64, 128] + 'train_batch_size': [4, 8, 16, 32, 64, 128], }) var_configs = OrderedDict({ @@ -57,8 +57,8 @@ "num_atoms": 1, "prioritized_replay": False, "prioritized_replay_alpha": 0.5, - #"sample_batch_size": 4, - "rollout_fragment_length":4, + "sample_batch_size": 4, + #"rollout_fragment_length":4, "schedule_max_timesteps": 20000, "target_network_update_freq": 800, "timesteps_per_iteration": 1000, @@ -68,7 +68,7 @@ model_config = { "model": { - "fcnet_hiddens": [256, 256], + "fcnet_hiddens": [32, 32], "custom_preprocessor": "ohe", "custom_options": {}, # extra options to pass to your preprocessor "fcnet_activation": "tanh", diff --git a/experiments/rainbow_image_representations_tune_hps_cave_analysis.py b/experiments/rainbow_image_representations_tune_hps_cave_analysis.py new file mode 100644 index 0000000..73f04eb --- /dev/null +++ b/experiments/rainbow_image_representations_tune_hps_cave_analysis.py @@ -0,0 +1,151 @@ +'''###IMP dummy_seed should always be last in the order in the OrderedDict below!!! +''' +num_seeds = 5 + +from collections import OrderedDict +var_env_configs = OrderedDict({ + 'state_space_size': [8],#, 10, 12, 14] # [2**i for i in range(1,6)] + 'action_space_size': [8],#2, 4, 8, 16] # [2**i for i in range(1,6)] + 'delay': [0], # + [2**i for i in range(4)], + 'sequence_length': [1], #, 2, 3, 4],#i for i in range(1,4)] + 'reward_density': [0.25], # np.linspace(0.0, 1.0, num=5) + 'make_denser': [False], + 'terminal_state_density': [0.25], # np.linspace(0.1, 1.0, num=5) + 'transition_noise': [0],#, 0.01, 0.02, 0.10, 0.25] + 'reward_noise': [0],#, 1, 5, 10, 25] # Std dev. of normal dist. + 'image_representations': [True], + 'image_transforms': ['none'], #image_transforms, # ['shift', 'scale', 'flip', 'rotate', 'shift,scale,rotate,flip'] + 'image_width': [100], + 'image_height': [100], + 'dummy_seed': [i for i in range(num_seeds)], +}) + +var_agent_configs = OrderedDict({ + "learning_starts": [500, 1000, 2000], + "lr": [1e-3, 1e-4, 1e-5], # "lr": grid_search([1e-2, 1e-4, 1e-6]), + "n_step": [1,2,3,4], + "noisy": [True, False], + "target_network_update_freq": [8, 80, 800], +}) + + +# formula [(W−K+2P)/S]+1; for padding=same: P = ((S-1)*W - S + K)/2 +filters_84x84 = [ + [16, [8, 8], 4], # changes from 84x84x1 with padding 4 to 22x22x16 (or 26x26x16 for 100x100x1) + [32, [4, 4], 2], # changes to 11x11x32 with padding 2 (or 13x13x32 for 100x100x1) + [256, [11, 11], 1], # changes to 1x1x256 with padding 0 (or 3x3x256 for 100x100x1); this is the only layer with valid padding in Ray! +] + +filters_100x100 = [ + [16, [8, 8], 4], # changes from 84x84x1 with padding 4 to 22x22x16 (or 26x26x16 for 100x100x1) + [32, [4, 4], 2], # changes to 11x11x32 with padding 2 (or 13x13x32 for 100x100x1) + [64, [13, 13], 1], # changes to 1x1x64 with padding 0 (or 3x3x64 for 100x100x1); this is the only layer with valid padding in Ray! +] +# [num_outputs(=8 in this case), [1, 1], 1] conv2d appended by Ray always followed by a Dense layer with 1 output + +# filters_99x99 = [ +# [16, [8, 8], 4], # 51x51x16 +# [32, [4, 4], 2], +# [64, [13, 13], 1], +# ] + +filters_100x100_large = [ + [16, [8, 8], 4], + [32, [4, 4], 2], + [256, [13, 13], 1], +] + +filters_50x50 = [ + [16, [4, 4], 2], + [32, [4, 4], 2], + [64, [13, 13], 1], +] + +filters_400x400 = [ + [16, [32, 32], 16], + [32, [4, 4], 2], + [64, [13, 13], 1], +] + + +var_model_configs = OrderedDict({ + "conv_filters": [filters_100x100, filters_100x100_large], +}) + +var_configs = OrderedDict({ +"env": var_env_configs, +"agent": var_agent_configs, +"model": var_model_configs, +}) + +env_config = { + "env": "RLToy-v0", + "horizon": 100, + "env_config": { + 'seed': 0, #seed + 'state_space_type': 'discrete', + 'action_space_type': 'discrete', + 'generate_random_mdp': True, + 'repeats_in_sequences': False, + 'reward_scale': 1.0, + 'completely_connected': True, + }, +} + +algorithm = "DQN" +agent_config = { + "adam_epsilon": 1e-4, + "buffer_size": 1000000, + "double_q": True, + "dueling": True, + "exploration_final_eps": 0.01, + "exploration_fraction": 0.1, + "schedule_max_timesteps": 20000, + # "hiddens": None, + "num_atoms": 10, # [5, 10, 20] + "prioritized_replay": True, + "prioritized_replay_alpha": 0.75, # + "prioritized_replay_beta": 0.4, + "final_prioritized_replay_beta": 1.0, # + "beta_annealing_fraction": 1.0, # + + "sample_batch_size": 4, + "timesteps_per_iteration": 1000, + "train_batch_size": 32, + "min_iter_time_s": 0, +} + + +model_config = { + "model": { + "fcnet_hiddens": [256, 256], + # "custom_preprocessor": "ohe", + "custom_options": {}, # extra options to pass to your preprocessor + "conv_activation": "relu", + # "no_final_linear": False, + # "vf_share_layers": True, + # "fcnet_activation": "tanh", + "use_lstm": False, + "max_seq_len": 20, + "lstm_cell_size": 256, + "lstm_use_prev_action_reward": False, + }, +} + +from ray import tune +eval_config = { + "evaluation_interval": 1, # I think this means every x training_iterations + "evaluation_config": { + "explore": False, + "exploration_fraction": 0, + "exploration_final_eps": 0, + "evaluation_num_episodes": 10, + "horizon": 100, + "env_config": { + "dummy_eval": True, #hack Used to check if we are in evaluation mode or training mode inside Ray callback on_episode_end() to be able to write eval stats + 'transition_noise': 0 if "state_space_type" in env_config["env_config"] and env_config["env_config"]["state_space_type"] == "discrete" else tune.function(lambda a: a.normal(0, 0)), + 'reward_noise': tune.function(lambda a: a.normal(0, 0)), + 'action_loss_weight': 0.0, + } + }, +} diff --git a/mdp_playground/analysis/analysis.py b/mdp_playground/analysis/analysis.py index 22cb203..3b4c69a 100644 --- a/mdp_playground/analysis/analysis.py +++ b/mdp_playground/analysis/analysis.py @@ -8,8 +8,8 @@ class MDPP_Analysis(): '''Utility class to load and plot data for analysis of experiments from MDP Playground ''' - def __init__(self): - pass + def __init__(self, save_folder = None): + self.save_folder = save_folder def load_data(self, dir_name, exp_name, num_metrics=3, load_eval=True): #, max_total_configs=200): '''Loads training and evaluation data from given file @@ -36,9 +36,13 @@ def load_data(self, dir_name, exp_name, num_metrics=3, load_eval=True): #, max_t eval_curves: np.ndarray The loaded evaluation CSV with the columns the evaluation stats that were saved ''' - stats_file = dir_name + '/' + exp_name #Name of file to which benchmark stats were written self.stats_file = stats_file + if self.save_folder is None: + self.save_folder = self.stats_file.split('/')[-1] + else: + self.save_folder = self.save_folder + self.stats_file.split('/')[-1] + #folder to save figures if os.path.isfile(stats_file + '.csv'): print("\033[1;31mLoading data from a sequential run/already combined runs of experiment configurations.\033[0;0m") @@ -294,7 +298,8 @@ def plot_1d_dimensions(self, stats_data, save_fig=False, train=True, metric_num= plt.xlabel(self.axis_labels[0]) plt.ylabel(y_axis_label) if save_fig: - plt.savefig(self.stats_file.split('/')[-1] + ('_train' if train else '_eval') + '_final_reward_' + self.axis_labels[0].replace(' ','_') + '_' + str(self.metric_names[metric_num]) + '_1d.pdf', dpi=300, bbox_inches="tight") + x = self.save_folder + ('_train' if train else '_eval') + '_final_reward_' + self.axis_labels[0].replace(' ','_') + '_' + str(self.metric_names[metric_num]) + '_1d.pdf' + plt.savefig(self.save_folder + ('_train' if train else '_eval') + '_final_reward_' + self.axis_labels[0].replace(' ','_') + '_' + str(self.metric_names[metric_num]) + '_1d.pdf', dpi=300, bbox_inches="tight") plt.show() if len(to_plot_.shape) == 2: # Case when 2 meta-features were varied @@ -305,7 +310,7 @@ def plot_1d_dimensions(self, stats_data, save_fig=False, train=True, metric_num= plt.xlabel(self.axis_labels[1]) plt.ylabel(y_axis_label) if save_fig: - plt.savefig(self.stats_file.split('/')[-1] + ('_train' if train else '_eval') + '_final_reward_' + self.axis_labels[1].replace(' ','_') + '_' + str(self.metric_names[metric_num]) + '_1d.pdf', dpi=300, bbox_inches="tight") + plt.savefig(self.save_folder+ ('_train' if train else '_eval') + '_final_reward_' + self.axis_labels[1].replace(' ','_') + '_' + str(self.metric_names[metric_num]) + '_1d.pdf', dpi=300, bbox_inches="tight") plt.show() def plot_2d_heatmap(self, stats_data, save_fig=False, train=True, metric_num=-2): @@ -346,7 +351,7 @@ def plot_2d_heatmap(self, stats_data, save_fig=False, train=True, metric_num=-2) else: plt.xlabel(self.axis_labels[0]) if save_fig: - plt.savefig(self.stats_file.split('/')[-1] + ('_train' if train else '_eval') + '_final_reward_mean_heat_map_' + str(self.metric_names[metric_num]) + '.pdf', dpi=300, bbox_inches="tight") + plt.savefig(self.save_folder + ('_train' if train else '_eval') + '_final_reward_mean_heat_map_' + str(self.metric_names[metric_num]) + '.pdf', dpi=300, bbox_inches="tight") plt.show() std_dev_ = np.std(stats_data[..., metric_num], axis=self.seed_idx) #seed to_plot_ = np.squeeze(std_dev_) @@ -367,7 +372,7 @@ def plot_2d_heatmap(self, stats_data, save_fig=False, train=True, metric_num=-2) plt.xlabel(self.axis_labels[0]) # plt.tight_layout() if save_fig: - plt.savefig(self.stats_file.split('/')[-1] + ('_train' if train else '_eval') + '_final_reward_std_heat_map_' + str(self.metric_names[metric_num]) + '.pdf', dpi=300, bbox_inches="tight") + plt.savefig(self.save_folder + ('_train' if train else '_eval') + '_final_reward_std_heat_map_' + str(self.metric_names[metric_num]) + '.pdf', dpi=300, bbox_inches="tight") # plt.savefig(stats_file.split('/')[-1] + '_train_heat_map.png')#, dpi=300) plt.show() @@ -437,4 +442,20 @@ def plot_learning_curves(self, stats_data, save_fig=False, train=True, metric_nu # plt.suptitle("Training Learning Curves") plt.show() if save_fig: - fig.savefig(self.stats_file.split('/')[-1] + ('_train' if train else '_eval') + '_learning_curves_' + str(self.metric_names[metric_num]) + '.pdf', dpi=300, bbox_inches="tight") # Generates high quality vector graphic PDF 125kb; dpi doesn't matter for this \ No newline at end of file + fig.savefig(self.save_folder + ('_train' if train else '_eval') + '_learning_curves_' + str(self.metric_names[metric_num]) + '.pdf', dpi=300, bbox_inches="tight") # Generates high quality vector graphic PDF 125kb; dpi doesn't matter for this + +if __name__ == "__main__": + # Set dir_name to the location where the CSV files from running an experiment were saved + dir_name = '../../../mdp_files/32_net' + # Set exp_name to the name that was given to the experiment when running it + exp_name = 'dqn_vanilla_train_bs' + # Set the following to True to save PDFs of plots that you generate below + save_fig = True + # Data loading + save_folder = "../../../plots/32_net/" + mdpp_analysis = MDPP_Analysis(save_folder) + train_stats, eval_stats, train_curves, eval_curves, train_aucs, eval_aucs = mdpp_analysis.load_data(dir_name, exp_name, load_eval=True) + # 1-D: Plots showing reward after 20k timesteps when varying a single meta-feature + # Plots across 10 runs: Training: with std dev across the runs + mdpp_analysis.plot_1d_dimensions(train_stats, save_fig) + mdpp_analysis.plot_1d_dimensions(train_aucs, save_fig) \ No newline at end of file diff --git a/mdp_playground/analysis/mdpp_to_cave.py b/mdp_playground/analysis/mdpp_to_cave.py new file mode 100644 index 0000000..87703a1 --- /dev/null +++ b/mdp_playground/analysis/mdpp_to_cave.py @@ -0,0 +1,232 @@ +import numpy as np +import pandas as pd +import argparse, os +import json + +class MDPPToCave(): + def __init__(self, output_dir = "../mdpp_to_cave/"): + self.output_folder = output_dir + if not os.path.exists(self.output_folder): + os.makedirs(self.output_folder) + + def _create_configspace_json(self, stats_pd, var_configs): + configspace = {"hyperparameters":[], + "conditions": [], + "forbiddens": [], + "python_module_version": "0.4.11", + "json_format_version": 0.1} + for param in var_configs: + param_config = {"name": param, + "type": "uniform_int", + } + var_type = str( type(stats_pd[param].iloc[0]) ) + if("int" in var_type or "bool" in var_type): + param_config["lower"] = int( stats_pd[param].min() ) + param_config["upper"] = int( stats_pd[param].max() ) + param_config["default"] = int(param_config["lower"] + param_config["upper"]//2) + param_config["type"] = "uniform_int" + else:#Float + param_config["lower"] = float( stats_pd[param].min() ) + param_config["upper"] = float( stats_pd[param].max() ) + param_config["default"] = (param_config["lower"] + param_config["upper"])//2 + param_config["type"] = "uniform_float" + + if "lr" in param: + param_config["log"] = True + else: + param_config["log"] = False + configspace["hyperparameters"].append(param_config) + return configspace + + def _create_run_history(self, stats_pd, seed_idx, col_names, output_folder, var_configs): + final_rows_for_a_config = [] + for i in range(stats_pd.shape[0] - 1): + if stats_pd["timesteps_total"].iloc[i] > stats_pd["timesteps_total"].iloc[ i + 1]: + final_rows_for_a_config.append(i) + final_rows_for_a_config.append(stats_pd.shape[0]-1) # Always append the last row! + + runhistory_col_names = ["cost","time","status","budget","seed"] + runhistory_df = pd.DataFrame(columns=runhistory_col_names) + runhistory_df["cost"] = -1 * stats_pd["episode_reward_mean"].iloc[final_rows_for_a_config] + runhistory_df["time"] = stats_pd["episode_len_mean"].iloc[final_rows_for_a_config] + runhistory_df["budget"] = stats_pd["timesteps_total"].iloc[final_rows_for_a_config] + if seed_idx > 0: + runhistory_df["seed"] = stats_pd[col_names[seed_idx]].iloc[final_rows_for_a_config] + else: + runhistory_df["seed"] = 0 + runhistory_df["status"] = "SUCCESS" + for var in var_configs: + runhistory_df[var] = stats_pd[var].iloc[final_rows_for_a_config] + return runhistory_df + + def to_cave_csv(self, args): + #file_path = args.file_path + input_folder = "../mdp_files/" + file_name = "dqn_vanilla_learning_starts" + output_folder = "../to_cave_format/%s"%file_name + if not os.path.exists(output_folder): + os.makedirs(output_folder) + + ## Read current csvs ## + stats_file = os.path.join(input_folder, file_name) + with open(stats_file + '.csv') as file_: + col_names = file_.readline().strip().split(', ') + col_names[0] = col_names[0][2:] # to remove '# ' that was written + # print("config_names:", col_names) + stats_pd = pd.read_csv(stats_file + '.csv', skip_blank_lines=True,\ + header=None, names = col_names, comment='#', sep=' ') + remove_names = ["training_iteration", "algorithm", "seed"] + + parameters = col_names[:-3].copy()#All paramaters tracked in run + for x in col_names: + for name in remove_names: + if(name in x): + parameters.remove(x) + + #Compute parameters that varied and store value in dict + config_values = {} + seed_idx = -1 + for i, c in enumerate(col_names): # hardcoded 3 for no. of stats written + if(c in parameters): #parameters we care about + config_values[c] = stats_pd[c].unique() #values a given parameter took + if("seed" in c): + seed_idx = i + var_configs = [p for p in parameters if len(config_values[p])>1] + + configspace = self._create_configspace_json(stats_pd, var_configs) + output_configspace = os.path.join(output_folder,'configspace.json') + with open(output_configspace, 'w') as fp: + json.dump(configspace, fp, indent=2) + + scenario_str = "paramfile = ./configspace.json\nrun_obj = quality" + output_configspace = os.path.join(output_folder,'scenario.txt') + with open(output_configspace, 'w') as fp: + fp.write(scenario_str) + + #Runhistory and trajectory files + runhistory_df = self._create_run_history(stats_pd, seed_idx, col_names, output_folder, var_configs) + runhistory_df.to_csv( os.path.join(output_folder,'runhistory.csv'), header=True, index=False) + + ## Creates the bohb file from the mdpp output in the output_folder directory + ## this file can be fed into cave for analysis + def to_bohb_results(self, dir_name, exp_name): + #file_path = args.file_path + output_folder = os.path.join(self.output_folder, exp_name) + if not os.path.exists(output_folder): + os.makedirs(output_folder) + + ## Read current csvs ## + stats_file = os.path.join(dir_name, exp_name) + with open(stats_file + '.csv') as file_: + col_names = file_.readline().strip().split(', ') + col_names[0] = col_names[0][2:] # to remove '# ' that was written + # print("config_names:", col_names) + stats_pd = pd.read_csv(stats_file + '.csv', skip_blank_lines=True,\ + header=None, names = col_names, comment='#', sep=' ') + remove_names = ["training_iteration", "algorithm", "seed"] + + parameters = col_names[:-3].copy()#All paramaters tracked in run + for x in col_names: + for name in remove_names: + if(name in x): + parameters.remove(x) + + #Compute parameters that varied and store value in dict + config_values = {} + seed_idx = -1 + for i, c in enumerate(col_names): # hardcoded 3 for no. of stats written + if(c in parameters): #parameters we care about + config_values[c] = stats_pd[c].unique() #values a given parameter took + if("seed" in c): + seed_idx = i + var_configs = [p for p in parameters if len(config_values[p])>1] + + final_rows_for_a_config = [] + for i in range(stats_pd.shape[0] - 1): + if stats_pd["timesteps_total"].iloc[i] > stats_pd["timesteps_total"].iloc[ i + 1]: + final_rows_for_a_config.append(i) + final_rows_for_a_config.append(stats_pd.shape[0]-1) # Always append the last row! + + ##------------- Start converting csv ----------------## + #configspace and scenario file + configspace = self._create_configspace_json(stats_pd, var_configs) + output_configspace = os.path.join(output_folder,'configspace.json') + with open(output_configspace, 'w') as fp: + json.dump(configspace, fp, indent=2) + + #Trajectory and runhistory files + #Finding end configuration training + diff_configs = stats_pd.iloc[final_rows_for_a_config] + diff_configs = diff_configs.groupby(var_configs) + configs_mean = diff_configs.mean() + diff_configs_results = [] #results.json + diff_configs_lst = [] + budget = stats_pd["timesteps_total"].iloc[final_rows_for_a_config[0]]#all have the same budget + aux = 0 + for i, group_name in enumerate(diff_configs.groups): + group_labels = diff_configs.groups[group_name] + config_id = [0, 0, i] + config_dict = {} + #configs.json + config_lst = [config_id] + for name in var_configs: + config_dict[name] = stats_pd[name].iloc[group_labels[0]].item() + config_lst.append(config_dict) + config_lst.append({"model_based_pick": False}) + diff_configs_lst.append(config_lst) + + #results.json + mean_reward = configs_mean["episode_reward_mean"].iloc[i]#mean along seed + results_lst=[config_id, budget.item(), {"submitted": float("%.2f"%aux), + "started": float("%.2f"%(aux + 0.1)), + "finished": float("%.2f"%(aux + 1)),} ] + aux += 1.1 + results_dict = {"loss": -mean_reward.item(), + "info": {}} + results_lst.append(results_dict) + results_lst.append(None) + diff_configs_results.append(results_lst) + + #configs.json + output_configs = os.path.join(output_folder,'configs.json') + with open(output_configs, 'w') as fout: + for d in diff_configs_lst: + json.dump(d, fout) + fout.write('\n') + + #results.json + output_configs = os.path.join(output_folder,'results.json') + with open(output_configs, 'w') as fout: + for d in diff_configs_results: + json.dump(d, fout) + fout.write('\n') + return output_folder + +if __name__ == "__main__": + dir_name = '../../../mdp_files/' + exp_name = 'dqn_seq_del' + + from cave.cavefacade import CAVE + import os + #The converted mdpp csvs will be stored in output_dir + output_dir = "../../../mdpp_to_cave" + mdpp_file = os.path.join(dir_name, exp_name) + mdpp_cave = MDPPToCave(output_dir) + cave_input_file = mdpp_cave.to_bohb_results(dir_name, exp_name) + + cave_input_file = "../../../mdpp_to_cave/dqn_seq_del" + + # Similarly, as an example, cave will ouput it's results + # to the same directory as cave's input files + + cave_results = os.path.join(cave_input_file, "output") + print(os.path.abspath(cave_results)) + cave = CAVE(folders = [cave_input_file], + output_dir = cave_results, + ta_exec_dir = [cave_input_file], + file_format = "BOHB", + show_jupyter=True, + ) + + #cave.plot_scatter() + cave.pimp_forward_selection() \ No newline at end of file diff --git a/plot_experiments.ipynb b/plot_experiments.ipynb index b9eca09..8663fc3 100644 --- a/plot_experiments.ipynb +++ b/plot_experiments.ipynb @@ -2,16 +2,16 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# Setup to analyse an MDP Playground experiment\n", "from mdp_playground.analysis import MDPP_Analysis\n", "# Set dir_name to the location where the CSV files from running an experiment were saved\n", - "dir_name = '/home/rajanr/mdpp_8837245'\n", + "dir_name = '../mdp_files/'\n", "# Set exp_name to the name that was given to the experiment when running it\n", - "exp_name = 'rainbow_space_invaders_r_noise' #'sac_halfcheetah_action_max'\n", + "exp_name = 'dqn_seq_del'\n", "# Set the following to True to save PDFs of plots that you generate below\n", "save_fig = True" ] @@ -25,8 +25,9 @@ "outputs": [], "source": [ "# Data loading\n", - "mdpp_analysis = MDPP_Analysis()\n", - "train_stats, eval_stats, train_curves, eval_curves, train_aucs, eval_aucs = mdpp_analysis.load_data(dir_name, exp_name, load_eval=False)" + "save_folder = \"../mdp_files/plots/\"\n", + "mdpp_analysis = MDPP_Analysis(save_folder)\n", + "train_stats, eval_stats, train_curves, eval_curves, train_aucs, eval_aucs = mdpp_analysis.load_data(dir_name, exp_name, load_eval=True)" ] }, { @@ -114,6 +115,3567 @@ "mdpp_analysis.plot_learning_curves(eval_curves, save_fig, train=False)" ] }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/sklearn/utils/deprecation.py:143: FutureWarning: The sklearn.metrics.regression module is deprecated in version 0.22 and will be removed in version 0.24. The corresponding classes / functions should instead be imported from sklearn.metrics. Anything that cannot be imported from sklearn.metrics is now part of the private API.\n", + " warnings.warn(message, FutureWarning)\n", + "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/sklearn/utils/deprecation.py:143: FutureWarning: The sklearn.manifold.mds module is deprecated in version 0.22 and will be removed in version 0.24. The corresponding classes / functions should instead be imported from sklearn.manifold. Anything that cannot be imported from sklearn.manifold is now part of the private API.\n", + " warnings.warn(message, FutureWarning)\n" + ] + } + ], + "source": [ + "from cave.cavefacade import CAVE\n", + "from mdp_playground.analysis.mdpp_to_cave import MDPPToCave\n", + "import os\n", + "\n", + "#The converted mdpp csvs will be stored in output_dir\n", + "output_dir = \"../mdpp_to_cave\"\n", + "mdpp_file = os.path.join(dir_name, exp_name)\n", + "mdpp_cave = MDPPToCave(output_dir)\n", + "cave_input_file = mdpp_cave.to_bohb_results(dir_name, exp_name)\n", + "\n", + "cave_input_file = \"../mdpp_to_cave/dqn_seq_del\"\n", + "\n", + "# Similarly, as an example, cave will ouput it's results \n", + "# to the same directory as cave's input files\n", + "\n", + "cave_results = os.path.join(cave_input_file, \"out\")\n", + "cave = CAVE(folders = [cave_input_file],\n", + " output_dir = cave_results,\n", + " ta_exec_dir = [cave_input_file],\n", + " file_format = \"BOHB\",\n", + " show_jupyter=True,\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "
\n", + "
\n", + "
General

General information about the optimization scenario.

\n", + "
\n", + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
# parameters2
Deterministic target algorithmTrue
Optimized run objectivequality
--------------------
Total time spent evaluating configurations18.00 sec
Average time per configuration (mean / std)0.90 sec (± 0.00)
# evaluated configurations20
# changed parameters (default to incumbent)2
Configuration originsRandom : 20
\n", + "
\n", + "
Budgets

Statistics related to the budgets used in this optimization.

\n", + "
\n", + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
20000
Total time spent evaluating configurations18.00 sec
Average time per configuration (mean / std)0.90 sec (± 0.00)
# evaluated configurations20
# changed parameters (default to incumbent)2
Configuration originsRandom : 20
\n", + "
\n", + "
Configuration Space

The parameter configuration space. (See github.com/automl/ConfigSpace)

\n", + "
\n", + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ParameterTypeRange/ChoicesDefault
delayUniformIntegerHyperparameter[0, 8]4
sequence_lengthUniformIntegerHyperparameter[1, 4]3
\n", + "
\n", + "
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cave.overview_table()" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "
\n", + "
\n", + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
DefaultIncumbent
--------------- Changed parameters: -------------------------
delay40
sequence_length31
\n", + "
\n", + "
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cave.compare_default_incumbent()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "
\n", + "
\n", + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
DefaultIncumbent
Quality-32.566-88.246
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cave.performance_table()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
\n", + " \n", + " Loading BokehJS ...\n", + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "\n", + "(function(root) {\n", + " function now() {\n", + " return new Date();\n", + " }\n", + "\n", + " var force = true;\n", + "\n", + " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", + " root._bokeh_onload_callbacks = [];\n", + " root._bokeh_is_loading = undefined;\n", + " }\n", + "\n", + " var JS_MIME_TYPE = 'application/javascript';\n", + " var HTML_MIME_TYPE = 'text/html';\n", + " var EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n", + " var CLASS_NAME = 'output_bokeh rendered_html';\n", + "\n", + " /**\n", + " * Render data to the DOM node\n", + " */\n", + " function render(props, node) {\n", + " var script = document.createElement(\"script\");\n", + " node.appendChild(script);\n", + " }\n", + "\n", + " /**\n", + " * Handle when an output is cleared or removed\n", + " */\n", + " function handleClearOutput(event, handle) {\n", + " var cell = handle.cell;\n", + "\n", + " var id = cell.output_area._bokeh_element_id;\n", + " var server_id = cell.output_area._bokeh_server_id;\n", + " // Clean up Bokeh references\n", + " if (id != null && id in Bokeh.index) {\n", + " Bokeh.index[id].model.document.clear();\n", + " delete Bokeh.index[id];\n", + " }\n", + "\n", + " if (server_id !== undefined) {\n", + " // Clean up Bokeh references\n", + " var cmd = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n", + " cell.notebook.kernel.execute(cmd, {\n", + " iopub: {\n", + " output: function(msg) {\n", + " var id = msg.content.text.trim();\n", + " if (id in Bokeh.index) {\n", + " Bokeh.index[id].model.document.clear();\n", + " delete Bokeh.index[id];\n", + " }\n", + " }\n", + " }\n", + " });\n", + " // Destroy server and session\n", + " var cmd = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n", + " cell.notebook.kernel.execute(cmd);\n", + " }\n", + " }\n", + "\n", + " /**\n", + " * Handle when a new output is added\n", + " */\n", + " function handleAddOutput(event, handle) {\n", + " var output_area = handle.output_area;\n", + " var output = handle.output;\n", + "\n", + " // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n", + " if ((output.output_type != \"display_data\") || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", + " return\n", + " }\n", + "\n", + " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", + "\n", + " if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n", + " toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n", + " // store reference to embed id on output_area\n", + " output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", + " }\n", + " if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", + " var bk_div = document.createElement(\"div\");\n", + " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", + " var script_attrs = bk_div.children[0].attributes;\n", + " for (var i = 0; i < script_attrs.length; i++) {\n", + " toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n", + " }\n", + " // store reference to server id on output_area\n", + " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", + " }\n", + " }\n", + "\n", + " function register_renderer(events, OutputArea) {\n", + "\n", + " function append_mime(data, metadata, element) {\n", + " // create a DOM node to render to\n", + " var toinsert = this.create_output_subarea(\n", + " metadata,\n", + " CLASS_NAME,\n", + " EXEC_MIME_TYPE\n", + " );\n", + " this.keyboard_manager.register_events(toinsert);\n", + " // Render to node\n", + " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", + " render(props, toinsert[toinsert.length - 1]);\n", + " element.append(toinsert);\n", + " return toinsert\n", + " }\n", + "\n", + " /* Handle when an output is cleared or removed */\n", + " events.on('clear_output.CodeCell', handleClearOutput);\n", + " events.on('delete.Cell', handleClearOutput);\n", + "\n", + " /* Handle when a new output is added */\n", + " events.on('output_added.OutputArea', handleAddOutput);\n", + "\n", + " /**\n", + " * Register the mime type and append_mime function with output_area\n", + " */\n", + " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", + " /* Is output safe? */\n", + " safe: true,\n", + " /* Index of renderer in `output_area.display_order` */\n", + " index: 0\n", + " });\n", + " }\n", + "\n", + " // register the mime type if in Jupyter Notebook environment and previously unregistered\n", + " if (root.Jupyter !== undefined) {\n", + " var events = require('base/js/events');\n", + " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", + "\n", + " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", + " register_renderer(events, OutputArea);\n", + " }\n", + " }\n", + "\n", + " \n", + " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", + " root._bokeh_timeout = Date.now() + 5000;\n", + " root._bokeh_failed_load = false;\n", + " }\n", + "\n", + " var NB_LOAD_WARNING = {'data': {'text/html':\n", + " \"
\\n\"+\n", + " \"

\\n\"+\n", + " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", + " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", + " \"

\\n\"+\n", + " \"
    \\n\"+\n", + " \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n", + " \"
  • use INLINE resources instead, as so:
  • \\n\"+\n", + " \"
\\n\"+\n", + " \"\\n\"+\n", + " \"from bokeh.resources import INLINE\\n\"+\n", + " \"output_notebook(resources=INLINE)\\n\"+\n", + " \"\\n\"+\n", + " \"
\"}};\n", + "\n", + " function display_loaded() {\n", + " var el = document.getElementById(\"1005\");\n", + " if (el != null) {\n", + " el.textContent = \"BokehJS is loading...\";\n", + " }\n", + " if (root.Bokeh !== undefined) {\n", + " if (el != null) {\n", + " el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n", + " }\n", + " } else if (Date.now() < root._bokeh_timeout) {\n", + " setTimeout(display_loaded, 100)\n", + " }\n", + " }\n", + "\n", + "\n", + " function run_callbacks() {\n", + " try {\n", + " root._bokeh_onload_callbacks.forEach(function(callback) {\n", + " if (callback != null)\n", + " callback();\n", + " });\n", + " } finally {\n", + " delete root._bokeh_onload_callbacks\n", + " }\n", + " console.debug(\"Bokeh: all callbacks have finished\");\n", + " }\n", + "\n", + " function load_libs(css_urls, js_urls, callback) {\n", + " if (css_urls == null) css_urls = [];\n", + " if (js_urls == null) js_urls = [];\n", + "\n", + " root._bokeh_onload_callbacks.push(callback);\n", + " if (root._bokeh_is_loading > 0) {\n", + " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", + " return null;\n", + " }\n", + " if (js_urls == null || js_urls.length === 0) {\n", + " run_callbacks();\n", + " return null;\n", + " }\n", + " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", + " root._bokeh_is_loading = css_urls.length + js_urls.length;\n", + "\n", + " function on_load() {\n", + " root._bokeh_is_loading--;\n", + " if (root._bokeh_is_loading === 0) {\n", + " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", + " run_callbacks()\n", + " }\n", + " }\n", + "\n", + " function on_error() {\n", + " console.error(\"failed to load \" + url);\n", + " }\n", + "\n", + " for (var i = 0; i < css_urls.length; i++) {\n", + " var url = css_urls[i];\n", + " const element = document.createElement(\"link\");\n", + " element.onload = on_load;\n", + " element.onerror = on_error;\n", + " element.rel = \"stylesheet\";\n", + " element.type = \"text/css\";\n", + " element.href = url;\n", + " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", + " document.body.appendChild(element);\n", + " }\n", + "\n", + " for (var i = 0; i < js_urls.length; i++) {\n", + " var url = js_urls[i];\n", + " var element = document.createElement('script');\n", + " element.onload = on_load;\n", + " element.onerror = on_error;\n", + " element.async = false;\n", + " element.src = url;\n", + " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", + " document.head.appendChild(element);\n", + " }\n", + " };var element = document.getElementById(\"1005\");\n", + " if (element == null) {\n", + " console.error(\"Bokeh: ERROR: autoload.js configured with elementid '1005' but no matching script tag was found. \")\n", + " return false;\n", + " }\n", + "\n", + " function inject_raw_css(css) {\n", + " const element = document.createElement(\"style\");\n", + " element.appendChild(document.createTextNode(css));\n", + " document.body.appendChild(element);\n", + " }\n", + "\n", + " var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.1.0.min.js\"];\n", + " var css_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.css\"];\n", + "\n", + " var inline_js = [\n", + " function(Bokeh) {\n", + " Bokeh.set_log_level(\"info\");\n", + " },\n", + " \n", + " function(Bokeh) {\n", + " (function(root, factory) {\n", + " // if(typeof exports === 'object' && typeof module === 'object')\n", + " // factory(require(\"Bokeh\"));\n", + " // else if(typeof define === 'function' && define.amd)\n", + " // define([\"Bokeh\"], factory);\n", + " // else if(typeof exports === 'object')\n", + " // factory(require(\"Bokeh\"));\n", + " // else\n", + " factory(root[\"Bokeh\"]);\n", + " })(this, function(Bokeh) {\n", + " var define;\n", + " return (function outer(modules, entry) {\n", + " if (Bokeh != null) {\n", + " return Bokeh.register_plugin(modules, {}, entry);\n", + " } else {\n", + " throw new Error(\"Cannot find Bokeh. You have to load it prior to loading plugins.\");\n", + " }\n", + " })\n", + " ({\n", + " \"custom/main\": function(require, module, exports) {\n", + " var models = {\n", + " \"ParallelResetTool\": require(\"custom/cave.plot.parallel_plot.parallel_reset.parallel_reset_tool\").ParallelResetTool,\n", + " \"ParallelSelectionTool\": require(\"custom/cave.plot.parallel_plot.parallel_selection_tool.parallel_selection_tool\").ParallelSelectionTool\n", + " };\n", + " require(\"base\").register_models(models);\n", + " module.exports = models;\n", + " },\n", + " \"custom/cave.plot.parallel_plot.parallel_reset.parallel_reset_tool\": function(require, module, exports) {\n", + " \"use strict\";\n", + " var __extends = (this && this.__extends) || (function () {\n", + " var extendStatics = function (d, b) {\n", + " extendStatics = Object.setPrototypeOf ||\n", + " ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n", + " function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n", + " return extendStatics(d, b);\n", + " };\n", + " return function (d, b) {\n", + " extendStatics(d, b);\n", + " function __() { this.constructor = d; }\n", + " d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n", + " };\n", + " })();\n", + " Object.defineProperty(exports, \"__esModule\", { value: true });\n", + " var action_tool_1 = require(\"models/tools/actions/action_tool\");\n", + " var ParallelResetToolView = /** @class */ (function (_super) {\n", + " __extends(ParallelResetToolView, _super);\n", + " function ParallelResetToolView() {\n", + " return _super !== null && _super.apply(this, arguments) || this;\n", + " }\n", + " ParallelResetToolView.prototype.doit = function () {\n", + " this.plot_view.reset_range();\n", + " };\n", + " return ParallelResetToolView;\n", + " }(action_tool_1.ActionToolView));\n", + " exports.ParallelResetToolView = ParallelResetToolView;\n", + " var ParallelResetTool = /** @class */ (function (_super) {\n", + " __extends(ParallelResetTool, _super);\n", + " function ParallelResetTool(attrs) {\n", + " var _this = _super.call(this, attrs) || this;\n", + " _this.tool_name = \"Reset Zoom\";\n", + " _this.icon = \"bk-tool-icon-reset\";\n", + " return _this;\n", + " }\n", + " ParallelResetTool.initClass = function () {\n", + " this.prototype.type = \"ParallelResetTool\";\n", + " this.prototype.default_view = ParallelResetToolView;\n", + " };\n", + " return ParallelResetTool;\n", + " }(action_tool_1.ActionTool));\n", + " exports.ParallelResetTool = ParallelResetTool;\n", + " ParallelResetTool.initClass();\n", + "\n", + " },\n", + " \"custom/cave.plot.parallel_plot.parallel_selection_tool.parallel_selection_tool\": function(require, module, exports) {\n", + " \"use strict\";\n", + " var __extends = (this && this.__extends) || (function () {\n", + " var extendStatics = function (d, b) {\n", + " extendStatics = Object.setPrototypeOf ||\n", + " ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n", + " function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n", + " return extendStatics(d, b);\n", + " };\n", + " return function (d, b) {\n", + " extendStatics(d, b);\n", + " function __() { this.constructor = d; }\n", + " d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n", + " };\n", + " })();\n", + " Object.defineProperty(exports, \"__esModule\", { value: true });\n", + " var p = require(\"core/properties\");\n", + " var box_select_tool_1 = require(\"models/tools/gestures/box_select_tool\");\n", + " var array_1 = require(\"core/util/array\");\n", + " var dom_1 = require(\"core/dom\");\n", + " function find_indices_in(array, _a) {\n", + " var inf = _a[0], sup = _a[1];\n", + " return array.reduce(function (prev, curr, index) {\n", + " return (inf <= curr && curr <= sup) ? prev.concat(index) : prev;\n", + " }, []);\n", + " }\n", + " function index_array(array, indices) {\n", + " return indices.reduce(function (a, i) { return a.concat(array[i]); }, []);\n", + " }\n", + " function combineByKey(key, array) {\n", + " var keys = Object.keys(array[0]);\n", + " var combined = [];\n", + " array.forEach(function (itm) {\n", + " var idx = combined.map(function (item) { return item[key]; }).indexOf(itm[key]);\n", + " if (idx >= 0) {\n", + " keys.forEach(function (element) {\n", + " if (element != key)\n", + " combined[idx][element].push(itm[element]);\n", + " });\n", + " }\n", + " else {\n", + " var new_object_1 = {};\n", + " keys.forEach(function (element) {\n", + " if (element == key) {\n", + " new_object_1[element] = itm[element];\n", + " }\n", + " else {\n", + " new_object_1[element] = [itm[element]];\n", + " }\n", + " });\n", + " combined.push(new_object_1);\n", + " }\n", + " });\n", + " return combined;\n", + " }\n", + " var ParallelSelectionView = /** @class */ (function (_super) {\n", + " __extends(ParallelSelectionView, _super);\n", + " function ParallelSelectionView() {\n", + " var _this = _super !== null && _super.apply(this, arguments) || this;\n", + " _this.selection_mode = \"add\";\n", + " _this.panning = false;\n", + " return _this;\n", + " }\n", + " ParallelSelectionView.prototype.initialize = function () {\n", + " var _this = this;\n", + " _super.prototype.initialize.call(this);\n", + " var frame = this.plot_view.frame;\n", + " var _a = this.model.renderer_select, x_range_name_select = _a.x_range_name, y_range_name_select = _a.y_range_name;\n", + " var _b = this.model.renderer_data, x_range_name_data = _b.x_range_name, y_range_name_data = _b.y_range_name;\n", + " if (x_range_name_select == x_range_name_data && y_range_name_select == y_range_name_data) {\n", + " this.xscale = frame.xscales[x_range_name_select];\n", + " this.yscale = frame.yscales[y_range_name_select];\n", + " }\n", + " else\n", + " throw new Error(\"selection and data does not share the same ranges\");\n", + " //TODO test if parallel CDS is valid (xs for each line should be identical)\n", + " this.glyph_select = this.model.renderer_select.glyph;\n", + " this.glyph_data = this.model.renderer_data.glyph;\n", + " this.cds_select = this.model.renderer_select.data_source;\n", + " this.cds_data = this.model.renderer_data.data_source;\n", + " var _c = [this.glyph_data.xs.field, this.glyph_data.ys.field], xskey = _c[0], yskey = _c[1];\n", + " this.xdata = this.cds_data.get_array(xskey)[0];\n", + " this.ydataT = array_1.transpose(this.cds_data.get_array(yskey));\n", + " this.selection_indices = [];\n", + " this.connect(this.plot_view.frame.x_ranges[this.model.renderer_select.x_range_name].change, function () { return _this._resize_boxes_on_zoom(); });\n", + " this.connect(this.cds_select.change, function () { return _this._update_data_selection(); });\n", + " };\n", + " Object.defineProperty(ParallelSelectionView.prototype, \"_box_width\", {\n", + " get: function () {\n", + " return this.xscale.invert(this.model.box_width) - this.xscale.invert(0);\n", + " },\n", + " enumerable: true,\n", + " configurable: true\n", + " });\n", + " Object.defineProperty(ParallelSelectionView.prototype, \"_cds_select_keys\", {\n", + " get: function () {\n", + " var glyph_select = this.glyph_select;\n", + " var _a = [glyph_select.x.field, glyph_select.y.field], xkey = _a[0], ykey = _a[1];\n", + " var _b = [glyph_select.width.field, glyph_select.height.field], wkey = _b[0], hkey = _b[1];\n", + " return { xkey: xkey, ykey: ykey, wkey: wkey, hkey: hkey };\n", + " },\n", + " enumerable: true,\n", + " configurable: true\n", + " });\n", + " ParallelSelectionView.prototype._emit_cds_changes = function (cds, redraw, clear, emit) {\n", + " if (redraw === void 0) { redraw = true; }\n", + " if (clear === void 0) { clear = true; }\n", + " if (emit === void 0) { emit = true; }\n", + " if (clear)\n", + " cds.selection_manager.clear();\n", + " if (redraw)\n", + " cds.change.emit();\n", + " if (emit) {\n", + " cds.data = cds.data;\n", + " cds.properties.data.change.emit();\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._box_paramaters = function (index) {\n", + " var _a = this._cds_select_keys, xkey = _a.xkey, ykey = _a.ykey, wkey = _a.wkey, hkey = _a.hkey;\n", + " var x = this.cds_select.get_array(xkey)[index];\n", + " var y = this.cds_select.get_array(ykey)[index];\n", + " var w = this.cds_select.get_array(wkey)[index];\n", + " var h = this.cds_select.get_array(hkey)[index];\n", + " return { x: x, y: y, w: w, h: h };\n", + " };\n", + " ParallelSelectionView.prototype._hit_test_boxes = function (sx, sy) {\n", + " var nboxes = this.cds_select.get_length();\n", + " if (nboxes != 0 && nboxes != null) {\n", + " var _a = [this.xscale.invert(sx), this.yscale.invert(sy)], xtest = _a[0], ytest = _a[1];\n", + " for (var i = 0; i < nboxes; i++) {\n", + " var _b = this._box_paramaters(i), x = _b.x, y = _b.y, w = _b.w, h = _b.h;\n", + " if (xtest >= (x - w / 2) && xtest <= x + w / 2 &&\n", + " ytest >= (y - h / 2) && ytest <= y + h / 2) {\n", + " return i;\n", + " }\n", + " }\n", + " }\n", + " return null;\n", + " };\n", + " ParallelSelectionView.prototype._resize_boxes_on_zoom = function () {\n", + " //resize selection boxes when zooming to keep a constant (pixel) size\n", + " var cds = this.cds_select;\n", + " var array_width = cds.get_array(this.glyph_select.width.field);\n", + " var new_width = this._box_width;\n", + " array_width.forEach(function (_, i) { return array_width[i] = new_width; });\n", + " this._emit_cds_changes(cds, true, false, false);\n", + " };\n", + " ParallelSelectionView.prototype._drag_start = function (ev) {\n", + " //Save y position of the drag start\n", + " if (this.ind_active_box != null) {\n", + " this._base_point = [this.xscale.invert(ev.sx), this.yscale.invert(ev.sy)];\n", + " this._base_box_parameters = this._box_paramaters(this.ind_active_box);\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._update_box_ypos = function (index_box, delta_y) {\n", + " if (this._base_box_parameters != null) {\n", + " var cds = this.cds_select;\n", + " var ykey = this._cds_select_keys.ykey;\n", + " var _a = this._base_box_parameters, current_y = _a.y, h = _a.h;\n", + " var new_y = current_y + delta_y;\n", + " new_y = new_y - Math.max(0, (new_y + h / 2) - 1) - Math.min(0, (new_y - h / 2));\n", + " cds.get_array(ykey)[index_box] = new_y;\n", + " this._emit_cds_changes(cds, true, false, false);\n", + " this._update_selection_indices(index_box, [new_y - h / 2, new_y + h / 2]);\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._drag = function (ev) {\n", + " if (this.ind_active_box != null && this._base_point != null) {\n", + " var delta_y = this.yscale.invert(ev.sy) - this._base_point[1];\n", + " this._update_box_ypos(this.ind_active_box, delta_y);\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._drag_stop = function (_ev) {\n", + " this._base_point = null;\n", + " this._base_box_parameters = null;\n", + " };\n", + " ParallelSelectionView.prototype._pan_start = function (ev) {\n", + " this.panning = true;\n", + " switch (this.selection_mode) {\n", + " case \"add\": {\n", + " _super.prototype._pan_start.call(this, ev);\n", + " break;\n", + " }\n", + " case \"drag\": {\n", + " this._drag_start(ev);\n", + " break;\n", + " }\n", + " case \"resize\": {\n", + " break;\n", + " }\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._pan = function (ev) {\n", + " switch (this.selection_mode) {\n", + " case \"add\": {\n", + " _super.prototype._pan.call(this, ev);\n", + " break;\n", + " }\n", + " case \"drag\": {\n", + " this._drag(ev);\n", + " break;\n", + " }\n", + " case \"resize\": {\n", + " break;\n", + " }\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._pan_end = function (ev) {\n", + " switch (this.selection_mode) {\n", + " case \"add\": {\n", + " _super.prototype._pan_end.call(this, ev);\n", + " break;\n", + " }\n", + " case \"drag\": {\n", + " this._drag_stop(ev);\n", + " break;\n", + " }\n", + " case \"resize\": {\n", + " break;\n", + " }\n", + " }\n", + " this.panning = false;\n", + " };\n", + " ParallelSelectionView.prototype._move = function (ev) {\n", + " //Switch mode\n", + " if (this.panning) {\n", + " return;\n", + " }\n", + " this.ind_active_box = this._hit_test_boxes(ev.sx, ev.sy);\n", + " if (this.ind_active_box != null) {\n", + " this.selection_mode = \"drag\";\n", + " }\n", + " else {\n", + " this.selection_mode = \"add\";\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._doubletap = function (_ev) {\n", + " var _this = this;\n", + " //delete box on double tap\n", + " if (this.ind_active_box != null) {\n", + " this.cds_select.columns().forEach(function (key) {\n", + " _this.cds_select.get_array(key).splice(_this.ind_active_box, 1);\n", + " });\n", + " this._delete_selection_indices(this.ind_active_box);\n", + " this._emit_cds_changes(this.cds_select);\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._keyup = function (ev) {\n", + " var _this = this;\n", + " if (ev.keyCode == dom_1.Keys.Esc) {\n", + " var nelems_1 = this.cds_select.get_length();\n", + " if (nelems_1 != null) {\n", + " this.cds_select.columns().forEach(function (key) {\n", + " _this.cds_select.get_array(key).splice(0, nelems_1);\n", + " });\n", + " this.selection_indices.splice(0, nelems_1);\n", + " this._emit_cds_changes(this.cds_select);\n", + " }\n", + " this.plot_view.request_render();\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._update_data_selection = function () {\n", + " var selection_indices = [];\n", + " if (this.selection_indices.length > 0) {\n", + " var combined_selections = combineByKey('data_idx', this.selection_indices);\n", + " selection_indices = array_1.intersection.apply(void 0, [array_1.union.apply(void 0, combined_selections[0].indices)].concat(combined_selections.slice(1).map(function (elem) { return array_1.union.apply(void 0, elem.indices); })));\n", + " }\n", + " this.cds_data.selected.indices = selection_indices;\n", + " this.cds_data.change.emit();\n", + " };\n", + " ParallelSelectionView.prototype._make_selection_indices = function (indices, _a) {\n", + " var _this = this;\n", + " var _b;\n", + " var y0 = _a[0], y1 = _a[1];\n", + " (_b = this.selection_indices).push.apply(_b, indices.map(function (index) {\n", + " return {\n", + " data_idx: index,\n", + " indices: find_indices_in(_this.ydataT[index], [y0, y1]),\n", + " };\n", + " }));\n", + " };\n", + " ParallelSelectionView.prototype._update_selection_indices = function (index, _a) {\n", + " var y0 = _a[0], y1 = _a[1];\n", + " this.selection_indices[index].indices = find_indices_in(this.ydataT[this.selection_indices[index].data_idx], [y0, y1]);\n", + " };\n", + " ParallelSelectionView.prototype._delete_selection_indices = function (index) {\n", + " this.selection_indices.splice(index, 1);\n", + " };\n", + " ParallelSelectionView.prototype._make_box_select = function (xs, _a) {\n", + " var _this = this;\n", + " var y0 = _a[0], y1 = _a[1];\n", + " y0 = Math.max(0, y0);\n", + " y1 = Math.min(1, y1);\n", + " var y = (y0 + y1) / 2.;\n", + " var w = this._box_width;\n", + " var h = y1 - y0;\n", + " var _b = this._cds_select_keys, xkey = _b.xkey, ykey = _b.ykey, wkey = _b.wkey, hkey = _b.hkey;\n", + " xs.forEach(function (x) {\n", + " if (xkey)\n", + " _this.cds_select.get_array(xkey).push(x);\n", + " if (ykey)\n", + " _this.cds_select.get_array(ykey).push(y);\n", + " if (wkey)\n", + " _this.cds_select.get_array(wkey).push(w);\n", + " if (hkey)\n", + " _this.cds_select.get_array(hkey).push(h);\n", + " });\n", + " this._emit_cds_changes(this.cds_select);\n", + " };\n", + " ParallelSelectionView.prototype._do_select = function (_a, _b, _final, _append) {\n", + " var sx0 = _a[0], sx1 = _a[1];\n", + " var sy0 = _b[0], sy1 = _b[1];\n", + " if (_final === void 0) { _final = true; }\n", + " if (_append === void 0) { _append = true; }\n", + " // Get selection bbox in the data space\n", + " var _c = this.xscale.r_invert(sx0, sx1), x0 = _c[0], x1 = _c[1];\n", + " var _d = this.yscale.r_invert(sy0, sy1), y0 = _d[0], y1 = _d[1];\n", + " var x_indices = find_indices_in(this.xdata, [x0, x1]);\n", + " var xs = index_array(this.xdata, x_indices);\n", + " this._make_selection_indices(x_indices, [y0, y1]);\n", + " this._make_box_select(xs, [y0, y1]);\n", + " };\n", + " return ParallelSelectionView;\n", + " }(box_select_tool_1.BoxSelectToolView));\n", + " exports.ParallelSelectionView = ParallelSelectionView;\n", + " var ParallelSelectionTool = /** @class */ (function (_super) {\n", + " __extends(ParallelSelectionTool, _super);\n", + " function ParallelSelectionTool() {\n", + " var _this = _super !== null && _super.apply(this, arguments) || this;\n", + " _this.tool_name = \"Parallel Selection\";\n", + " //override event_type property define in BoxSelectTool\n", + " _this.event_type = [\"tap\", \"pan\", \"move\"];\n", + " return _this;\n", + " }\n", + " ParallelSelectionTool.initClass = function () {\n", + " this.prototype.type = \"ParallelSelectionTool\";\n", + " this.prototype.default_view = ParallelSelectionView;\n", + " this.define({\n", + " renderer_select: [p.Any],\n", + " renderer_data: [p.Any],\n", + " box_width: [p.Number, 30],\n", + " });\n", + " };\n", + " return ParallelSelectionTool;\n", + " }(box_select_tool_1.BoxSelectTool));\n", + " exports.ParallelSelectionTool = ParallelSelectionTool;\n", + " ParallelSelectionTool.initClass();\n", + "\n", + " }\n", + " }, \"custom/main\");\n", + " ;\n", + " });\n", + "\n", + " },\n", + " function(Bokeh) {} // ensure no trailing comma for IE\n", + " ];\n", + "\n", + " function run_inline_js() {\n", + " \n", + " if ((root.Bokeh !== undefined) || (force === true)) {\n", + " for (var i = 0; i < inline_js.length; i++) {\n", + " inline_js[i].call(root, root.Bokeh);\n", + " }if (force === true) {\n", + " display_loaded();\n", + " }} else if (Date.now() < root._bokeh_timeout) {\n", + " setTimeout(run_inline_js, 100);\n", + " } else if (!root._bokeh_failed_load) {\n", + " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", + " root._bokeh_failed_load = true;\n", + " } else if (force !== true) {\n", + " var cell = $(document.getElementById(\"1005\")).parents('.cell').data().cell;\n", + " cell.output_area.append_execute_result(NB_LOAD_WARNING)\n", + " }\n", + "\n", + " }\n", + "\n", + " if (root._bokeh_is_loading === 0) {\n", + " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", + " run_inline_js();\n", + " } else {\n", + " load_libs(css_urls, js_urls, function() {\n", + " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", + " run_inline_js();\n", + " });\n", + " }\n", + "}(window));" + ], + "application/vnd.bokehjs_load.v0+json": "\n(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n \n\n \n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n var NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n var el = document.getElementById(\"1005\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };var element = document.getElementById(\"1005\");\n if (element == null) {\n console.error(\"Bokeh: ERROR: autoload.js configured with elementid '1005' but no matching script tag was found. \")\n return false;\n }\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.1.0.min.js\"];\n var css_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.css\"];\n\n var inline_js = [\n function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n \n function(Bokeh) {\n (function(root, factory) {\n // if(typeof exports === 'object' && typeof module === 'object')\n // factory(require(\"Bokeh\"));\n // else if(typeof define === 'function' && define.amd)\n // define([\"Bokeh\"], factory);\n // else if(typeof exports === 'object')\n // factory(require(\"Bokeh\"));\n // else\n factory(root[\"Bokeh\"]);\n })(this, function(Bokeh) {\n var define;\n return (function outer(modules, entry) {\n if (Bokeh != null) {\n return Bokeh.register_plugin(modules, {}, entry);\n } else {\n throw new Error(\"Cannot find Bokeh. You have to load it prior to loading plugins.\");\n }\n })\n ({\n \"custom/main\": function(require, module, exports) {\n var models = {\n \"ParallelResetTool\": require(\"custom/cave.plot.parallel_plot.parallel_reset.parallel_reset_tool\").ParallelResetTool,\n \"ParallelSelectionTool\": require(\"custom/cave.plot.parallel_plot.parallel_selection_tool.parallel_selection_tool\").ParallelSelectionTool\n };\n require(\"base\").register_models(models);\n module.exports = models;\n },\n \"custom/cave.plot.parallel_plot.parallel_reset.parallel_reset_tool\": function(require, module, exports) {\n \"use strict\";\n var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n })();\n Object.defineProperty(exports, \"__esModule\", { value: true });\n var action_tool_1 = require(\"models/tools/actions/action_tool\");\n var ParallelResetToolView = /** @class */ (function (_super) {\n __extends(ParallelResetToolView, _super);\n function ParallelResetToolView() {\n return _super !== null && _super.apply(this, arguments) || this;\n }\n ParallelResetToolView.prototype.doit = function () {\n this.plot_view.reset_range();\n };\n return ParallelResetToolView;\n }(action_tool_1.ActionToolView));\n exports.ParallelResetToolView = ParallelResetToolView;\n var ParallelResetTool = /** @class */ (function (_super) {\n __extends(ParallelResetTool, _super);\n function ParallelResetTool(attrs) {\n var _this = _super.call(this, attrs) || this;\n _this.tool_name = \"Reset Zoom\";\n _this.icon = \"bk-tool-icon-reset\";\n return _this;\n }\n ParallelResetTool.initClass = function () {\n this.prototype.type = \"ParallelResetTool\";\n this.prototype.default_view = ParallelResetToolView;\n };\n return ParallelResetTool;\n }(action_tool_1.ActionTool));\n exports.ParallelResetTool = ParallelResetTool;\n ParallelResetTool.initClass();\n\n },\n \"custom/cave.plot.parallel_plot.parallel_selection_tool.parallel_selection_tool\": function(require, module, exports) {\n \"use strict\";\n var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n })();\n Object.defineProperty(exports, \"__esModule\", { value: true });\n var p = require(\"core/properties\");\n var box_select_tool_1 = require(\"models/tools/gestures/box_select_tool\");\n var array_1 = require(\"core/util/array\");\n var dom_1 = require(\"core/dom\");\n function find_indices_in(array, _a) {\n var inf = _a[0], sup = _a[1];\n return array.reduce(function (prev, curr, index) {\n return (inf <= curr && curr <= sup) ? prev.concat(index) : prev;\n }, []);\n }\n function index_array(array, indices) {\n return indices.reduce(function (a, i) { return a.concat(array[i]); }, []);\n }\n function combineByKey(key, array) {\n var keys = Object.keys(array[0]);\n var combined = [];\n array.forEach(function (itm) {\n var idx = combined.map(function (item) { return item[key]; }).indexOf(itm[key]);\n if (idx >= 0) {\n keys.forEach(function (element) {\n if (element != key)\n combined[idx][element].push(itm[element]);\n });\n }\n else {\n var new_object_1 = {};\n keys.forEach(function (element) {\n if (element == key) {\n new_object_1[element] = itm[element];\n }\n else {\n new_object_1[element] = [itm[element]];\n }\n });\n combined.push(new_object_1);\n }\n });\n return combined;\n }\n var ParallelSelectionView = /** @class */ (function (_super) {\n __extends(ParallelSelectionView, _super);\n function ParallelSelectionView() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n _this.selection_mode = \"add\";\n _this.panning = false;\n return _this;\n }\n ParallelSelectionView.prototype.initialize = function () {\n var _this = this;\n _super.prototype.initialize.call(this);\n var frame = this.plot_view.frame;\n var _a = this.model.renderer_select, x_range_name_select = _a.x_range_name, y_range_name_select = _a.y_range_name;\n var _b = this.model.renderer_data, x_range_name_data = _b.x_range_name, y_range_name_data = _b.y_range_name;\n if (x_range_name_select == x_range_name_data && y_range_name_select == y_range_name_data) {\n this.xscale = frame.xscales[x_range_name_select];\n this.yscale = frame.yscales[y_range_name_select];\n }\n else\n throw new Error(\"selection and data does not share the same ranges\");\n //TODO test if parallel CDS is valid (xs for each line should be identical)\n this.glyph_select = this.model.renderer_select.glyph;\n this.glyph_data = this.model.renderer_data.glyph;\n this.cds_select = this.model.renderer_select.data_source;\n this.cds_data = this.model.renderer_data.data_source;\n var _c = [this.glyph_data.xs.field, this.glyph_data.ys.field], xskey = _c[0], yskey = _c[1];\n this.xdata = this.cds_data.get_array(xskey)[0];\n this.ydataT = array_1.transpose(this.cds_data.get_array(yskey));\n this.selection_indices = [];\n this.connect(this.plot_view.frame.x_ranges[this.model.renderer_select.x_range_name].change, function () { return _this._resize_boxes_on_zoom(); });\n this.connect(this.cds_select.change, function () { return _this._update_data_selection(); });\n };\n Object.defineProperty(ParallelSelectionView.prototype, \"_box_width\", {\n get: function () {\n return this.xscale.invert(this.model.box_width) - this.xscale.invert(0);\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(ParallelSelectionView.prototype, \"_cds_select_keys\", {\n get: function () {\n var glyph_select = this.glyph_select;\n var _a = [glyph_select.x.field, glyph_select.y.field], xkey = _a[0], ykey = _a[1];\n var _b = [glyph_select.width.field, glyph_select.height.field], wkey = _b[0], hkey = _b[1];\n return { xkey: xkey, ykey: ykey, wkey: wkey, hkey: hkey };\n },\n enumerable: true,\n configurable: true\n });\n ParallelSelectionView.prototype._emit_cds_changes = function (cds, redraw, clear, emit) {\n if (redraw === void 0) { redraw = true; }\n if (clear === void 0) { clear = true; }\n if (emit === void 0) { emit = true; }\n if (clear)\n cds.selection_manager.clear();\n if (redraw)\n cds.change.emit();\n if (emit) {\n cds.data = cds.data;\n cds.properties.data.change.emit();\n }\n };\n ParallelSelectionView.prototype._box_paramaters = function (index) {\n var _a = this._cds_select_keys, xkey = _a.xkey, ykey = _a.ykey, wkey = _a.wkey, hkey = _a.hkey;\n var x = this.cds_select.get_array(xkey)[index];\n var y = this.cds_select.get_array(ykey)[index];\n var w = this.cds_select.get_array(wkey)[index];\n var h = this.cds_select.get_array(hkey)[index];\n return { x: x, y: y, w: w, h: h };\n };\n ParallelSelectionView.prototype._hit_test_boxes = function (sx, sy) {\n var nboxes = this.cds_select.get_length();\n if (nboxes != 0 && nboxes != null) {\n var _a = [this.xscale.invert(sx), this.yscale.invert(sy)], xtest = _a[0], ytest = _a[1];\n for (var i = 0; i < nboxes; i++) {\n var _b = this._box_paramaters(i), x = _b.x, y = _b.y, w = _b.w, h = _b.h;\n if (xtest >= (x - w / 2) && xtest <= x + w / 2 &&\n ytest >= (y - h / 2) && ytest <= y + h / 2) {\n return i;\n }\n }\n }\n return null;\n };\n ParallelSelectionView.prototype._resize_boxes_on_zoom = function () {\n //resize selection boxes when zooming to keep a constant (pixel) size\n var cds = this.cds_select;\n var array_width = cds.get_array(this.glyph_select.width.field);\n var new_width = this._box_width;\n array_width.forEach(function (_, i) { return array_width[i] = new_width; });\n this._emit_cds_changes(cds, true, false, false);\n };\n ParallelSelectionView.prototype._drag_start = function (ev) {\n //Save y position of the drag start\n if (this.ind_active_box != null) {\n this._base_point = [this.xscale.invert(ev.sx), this.yscale.invert(ev.sy)];\n this._base_box_parameters = this._box_paramaters(this.ind_active_box);\n }\n };\n ParallelSelectionView.prototype._update_box_ypos = function (index_box, delta_y) {\n if (this._base_box_parameters != null) {\n var cds = this.cds_select;\n var ykey = this._cds_select_keys.ykey;\n var _a = this._base_box_parameters, current_y = _a.y, h = _a.h;\n var new_y = current_y + delta_y;\n new_y = new_y - Math.max(0, (new_y + h / 2) - 1) - Math.min(0, (new_y - h / 2));\n cds.get_array(ykey)[index_box] = new_y;\n this._emit_cds_changes(cds, true, false, false);\n this._update_selection_indices(index_box, [new_y - h / 2, new_y + h / 2]);\n }\n };\n ParallelSelectionView.prototype._drag = function (ev) {\n if (this.ind_active_box != null && this._base_point != null) {\n var delta_y = this.yscale.invert(ev.sy) - this._base_point[1];\n this._update_box_ypos(this.ind_active_box, delta_y);\n }\n };\n ParallelSelectionView.prototype._drag_stop = function (_ev) {\n this._base_point = null;\n this._base_box_parameters = null;\n };\n ParallelSelectionView.prototype._pan_start = function (ev) {\n this.panning = true;\n switch (this.selection_mode) {\n case \"add\": {\n _super.prototype._pan_start.call(this, ev);\n break;\n }\n case \"drag\": {\n this._drag_start(ev);\n break;\n }\n case \"resize\": {\n break;\n }\n }\n };\n ParallelSelectionView.prototype._pan = function (ev) {\n switch (this.selection_mode) {\n case \"add\": {\n _super.prototype._pan.call(this, ev);\n break;\n }\n case \"drag\": {\n this._drag(ev);\n break;\n }\n case \"resize\": {\n break;\n }\n }\n };\n ParallelSelectionView.prototype._pan_end = function (ev) {\n switch (this.selection_mode) {\n case \"add\": {\n _super.prototype._pan_end.call(this, ev);\n break;\n }\n case \"drag\": {\n this._drag_stop(ev);\n break;\n }\n case \"resize\": {\n break;\n }\n }\n this.panning = false;\n };\n ParallelSelectionView.prototype._move = function (ev) {\n //Switch mode\n if (this.panning) {\n return;\n }\n this.ind_active_box = this._hit_test_boxes(ev.sx, ev.sy);\n if (this.ind_active_box != null) {\n this.selection_mode = \"drag\";\n }\n else {\n this.selection_mode = \"add\";\n }\n };\n ParallelSelectionView.prototype._doubletap = function (_ev) {\n var _this = this;\n //delete box on double tap\n if (this.ind_active_box != null) {\n this.cds_select.columns().forEach(function (key) {\n _this.cds_select.get_array(key).splice(_this.ind_active_box, 1);\n });\n this._delete_selection_indices(this.ind_active_box);\n this._emit_cds_changes(this.cds_select);\n }\n };\n ParallelSelectionView.prototype._keyup = function (ev) {\n var _this = this;\n if (ev.keyCode == dom_1.Keys.Esc) {\n var nelems_1 = this.cds_select.get_length();\n if (nelems_1 != null) {\n this.cds_select.columns().forEach(function (key) {\n _this.cds_select.get_array(key).splice(0, nelems_1);\n });\n this.selection_indices.splice(0, nelems_1);\n this._emit_cds_changes(this.cds_select);\n }\n this.plot_view.request_render();\n }\n };\n ParallelSelectionView.prototype._update_data_selection = function () {\n var selection_indices = [];\n if (this.selection_indices.length > 0) {\n var combined_selections = combineByKey('data_idx', this.selection_indices);\n selection_indices = array_1.intersection.apply(void 0, [array_1.union.apply(void 0, combined_selections[0].indices)].concat(combined_selections.slice(1).map(function (elem) { return array_1.union.apply(void 0, elem.indices); })));\n }\n this.cds_data.selected.indices = selection_indices;\n this.cds_data.change.emit();\n };\n ParallelSelectionView.prototype._make_selection_indices = function (indices, _a) {\n var _this = this;\n var _b;\n var y0 = _a[0], y1 = _a[1];\n (_b = this.selection_indices).push.apply(_b, indices.map(function (index) {\n return {\n data_idx: index,\n indices: find_indices_in(_this.ydataT[index], [y0, y1]),\n };\n }));\n };\n ParallelSelectionView.prototype._update_selection_indices = function (index, _a) {\n var y0 = _a[0], y1 = _a[1];\n this.selection_indices[index].indices = find_indices_in(this.ydataT[this.selection_indices[index].data_idx], [y0, y1]);\n };\n ParallelSelectionView.prototype._delete_selection_indices = function (index) {\n this.selection_indices.splice(index, 1);\n };\n ParallelSelectionView.prototype._make_box_select = function (xs, _a) {\n var _this = this;\n var y0 = _a[0], y1 = _a[1];\n y0 = Math.max(0, y0);\n y1 = Math.min(1, y1);\n var y = (y0 + y1) / 2.;\n var w = this._box_width;\n var h = y1 - y0;\n var _b = this._cds_select_keys, xkey = _b.xkey, ykey = _b.ykey, wkey = _b.wkey, hkey = _b.hkey;\n xs.forEach(function (x) {\n if (xkey)\n _this.cds_select.get_array(xkey).push(x);\n if (ykey)\n _this.cds_select.get_array(ykey).push(y);\n if (wkey)\n _this.cds_select.get_array(wkey).push(w);\n if (hkey)\n _this.cds_select.get_array(hkey).push(h);\n });\n this._emit_cds_changes(this.cds_select);\n };\n ParallelSelectionView.prototype._do_select = function (_a, _b, _final, _append) {\n var sx0 = _a[0], sx1 = _a[1];\n var sy0 = _b[0], sy1 = _b[1];\n if (_final === void 0) { _final = true; }\n if (_append === void 0) { _append = true; }\n // Get selection bbox in the data space\n var _c = this.xscale.r_invert(sx0, sx1), x0 = _c[0], x1 = _c[1];\n var _d = this.yscale.r_invert(sy0, sy1), y0 = _d[0], y1 = _d[1];\n var x_indices = find_indices_in(this.xdata, [x0, x1]);\n var xs = index_array(this.xdata, x_indices);\n this._make_selection_indices(x_indices, [y0, y1]);\n this._make_box_select(xs, [y0, y1]);\n };\n return ParallelSelectionView;\n }(box_select_tool_1.BoxSelectToolView));\n exports.ParallelSelectionView = ParallelSelectionView;\n var ParallelSelectionTool = /** @class */ (function (_super) {\n __extends(ParallelSelectionTool, _super);\n function ParallelSelectionTool() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n _this.tool_name = \"Parallel Selection\";\n //override event_type property define in BoxSelectTool\n _this.event_type = [\"tap\", \"pan\", \"move\"];\n return _this;\n }\n ParallelSelectionTool.initClass = function () {\n this.prototype.type = \"ParallelSelectionTool\";\n this.prototype.default_view = ParallelSelectionView;\n this.define({\n renderer_select: [p.Any],\n renderer_data: [p.Any],\n box_width: [p.Number, 30],\n });\n };\n return ParallelSelectionTool;\n }(box_select_tool_1.BoxSelectTool));\n exports.ParallelSelectionTool = ParallelSelectionTool;\n ParallelSelectionTool.initClass();\n\n }\n }, \"custom/main\");\n ;\n });\n\n },\n function(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n \n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }if (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n var cell = $(document.getElementById(\"1005\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "(function(root) {\n", + " function embed_document(root) {\n", + " \n", + " var docs_json = {\"a844f449-2791-4215-a47f-20ccd4d4db43\":{\"roots\":{\"references\":[{\"attributes\":{\"columns\":[{\"id\":\"1002\",\"type\":\"TableColumn\"}],\"height\":20,\"index_position\":null,\"source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"},\"view\":{\"id\":\"1004\",\"type\":\"CDSView\"}},\"id\":\"1003\",\"type\":\"DataTable\"},{\"attributes\":{},\"id\":\"1007\",\"type\":\"StringEditor\"},{\"attributes\":{\"callback\":null,\"data\":{\"Parameters\":[]},\"selected\":{\"id\":\"1008\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1009\",\"type\":\"UnionRenderers\"}},\"id\":\"1001\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"1006\",\"type\":\"StringFormatter\"},{\"attributes\":{\"source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"}},\"id\":\"1004\",\"type\":\"CDSView\"},{\"attributes\":{\"default_sort\":\"descending\",\"editor\":{\"id\":\"1007\",\"type\":\"StringEditor\"},\"field\":\"Parameters\",\"formatter\":{\"id\":\"1006\",\"type\":\"StringFormatter\"},\"sortable\":false,\"title\":\"Parameters\",\"width\":150},\"id\":\"1002\",\"type\":\"TableColumn\"},{\"attributes\":{},\"id\":\"1008\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1009\",\"type\":\"UnionRenderers\"}],\"root_ids\":[\"1003\"]},\"title\":\"Bokeh Application\",\"version\":\"1.1.0\"}};\n", + " var render_items = [{\"docid\":\"a844f449-2791-4215-a47f-20ccd4d4db43\",\"roots\":{\"1003\":\"3710ea7b-cdcc-4825-840d-92930f9ced97\"}}];\n", + " root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", + "\n", + " }\n", + " if (root.Bokeh !== undefined) {\n", + " embed_document(root);\n", + " } else {\n", + " var attempts = 0;\n", + " var timer = setInterval(function(root) {\n", + " if (root.Bokeh !== undefined) {\n", + " embed_document(root);\n", + " clearInterval(timer);\n", + " }\n", + " attempts++;\n", + " if (attempts > 100) {\n", + " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n", + " clearInterval(timer);\n", + " }\n", + " }, 10, root)\n", + " }\n", + "})(window);" + ], + "application/vnd.bokehjs_exec.v0+json": "" + }, + "metadata": { + "application/vnd.bokehjs_exec.v0+json": { + "id": "1003" + } + }, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cave.pimp_comparison_table()" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "#As there are no instances, this will not show\n", + "cave.plot_scatter()\n", + "cave.plot_ecdf()\n", + "cave.algorithm_footprints()" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
\n", + " \n", + " Loading BokehJS ...\n", + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "\n", + "(function(root) {\n", + " function now() {\n", + " return new Date();\n", + " }\n", + "\n", + " var force = true;\n", + "\n", + " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", + " root._bokeh_onload_callbacks = [];\n", + " root._bokeh_is_loading = undefined;\n", + " }\n", + "\n", + " var JS_MIME_TYPE = 'application/javascript';\n", + " var HTML_MIME_TYPE = 'text/html';\n", + " var EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n", + " var CLASS_NAME = 'output_bokeh rendered_html';\n", + "\n", + " /**\n", + " * Render data to the DOM node\n", + " */\n", + " function render(props, node) {\n", + " var script = document.createElement(\"script\");\n", + " node.appendChild(script);\n", + " }\n", + "\n", + " /**\n", + " * Handle when an output is cleared or removed\n", + " */\n", + " function handleClearOutput(event, handle) {\n", + " var cell = handle.cell;\n", + "\n", + " var id = cell.output_area._bokeh_element_id;\n", + " var server_id = cell.output_area._bokeh_server_id;\n", + " // Clean up Bokeh references\n", + " if (id != null && id in Bokeh.index) {\n", + " Bokeh.index[id].model.document.clear();\n", + " delete Bokeh.index[id];\n", + " }\n", + "\n", + " if (server_id !== undefined) {\n", + " // Clean up Bokeh references\n", + " var cmd = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n", + " cell.notebook.kernel.execute(cmd, {\n", + " iopub: {\n", + " output: function(msg) {\n", + " var id = msg.content.text.trim();\n", + " if (id in Bokeh.index) {\n", + " Bokeh.index[id].model.document.clear();\n", + " delete Bokeh.index[id];\n", + " }\n", + " }\n", + " }\n", + " });\n", + " // Destroy server and session\n", + " var cmd = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n", + " cell.notebook.kernel.execute(cmd);\n", + " }\n", + " }\n", + "\n", + " /**\n", + " * Handle when a new output is added\n", + " */\n", + " function handleAddOutput(event, handle) {\n", + " var output_area = handle.output_area;\n", + " var output = handle.output;\n", + "\n", + " // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n", + " if ((output.output_type != \"display_data\") || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", + " return\n", + " }\n", + "\n", + " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", + "\n", + " if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n", + " toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n", + " // store reference to embed id on output_area\n", + " output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", + " }\n", + " if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", + " var bk_div = document.createElement(\"div\");\n", + " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", + " var script_attrs = bk_div.children[0].attributes;\n", + " for (var i = 0; i < script_attrs.length; i++) {\n", + " toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n", + " }\n", + " // store reference to server id on output_area\n", + " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", + " }\n", + " }\n", + "\n", + " function register_renderer(events, OutputArea) {\n", + "\n", + " function append_mime(data, metadata, element) {\n", + " // create a DOM node to render to\n", + " var toinsert = this.create_output_subarea(\n", + " metadata,\n", + " CLASS_NAME,\n", + " EXEC_MIME_TYPE\n", + " );\n", + " this.keyboard_manager.register_events(toinsert);\n", + " // Render to node\n", + " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", + " render(props, toinsert[toinsert.length - 1]);\n", + " element.append(toinsert);\n", + " return toinsert\n", + " }\n", + "\n", + " /* Handle when an output is cleared or removed */\n", + " events.on('clear_output.CodeCell', handleClearOutput);\n", + " events.on('delete.Cell', handleClearOutput);\n", + "\n", + " /* Handle when a new output is added */\n", + " events.on('output_added.OutputArea', handleAddOutput);\n", + "\n", + " /**\n", + " * Register the mime type and append_mime function with output_area\n", + " */\n", + " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", + " /* Is output safe? */\n", + " safe: true,\n", + " /* Index of renderer in `output_area.display_order` */\n", + " index: 0\n", + " });\n", + " }\n", + "\n", + " // register the mime type if in Jupyter Notebook environment and previously unregistered\n", + " if (root.Jupyter !== undefined) {\n", + " var events = require('base/js/events');\n", + " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", + "\n", + " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", + " register_renderer(events, OutputArea);\n", + " }\n", + " }\n", + "\n", + " \n", + " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", + " root._bokeh_timeout = Date.now() + 5000;\n", + " root._bokeh_failed_load = false;\n", + " }\n", + "\n", + " var NB_LOAD_WARNING = {'data': {'text/html':\n", + " \"
\\n\"+\n", + " \"

\\n\"+\n", + " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", + " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", + " \"

\\n\"+\n", + " \"
    \\n\"+\n", + " \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n", + " \"
  • use INLINE resources instead, as so:
  • \\n\"+\n", + " \"
\\n\"+\n", + " \"\\n\"+\n", + " \"from bokeh.resources import INLINE\\n\"+\n", + " \"output_notebook(resources=INLINE)\\n\"+\n", + " \"\\n\"+\n", + " \"
\"}};\n", + "\n", + " function display_loaded() {\n", + " var el = document.getElementById(\"4897\");\n", + " if (el != null) {\n", + " el.textContent = \"BokehJS is loading...\";\n", + " }\n", + " if (root.Bokeh !== undefined) {\n", + " if (el != null) {\n", + " el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n", + " }\n", + " } else if (Date.now() < root._bokeh_timeout) {\n", + " setTimeout(display_loaded, 100)\n", + " }\n", + " }\n", + "\n", + "\n", + " function run_callbacks() {\n", + " try {\n", + " root._bokeh_onload_callbacks.forEach(function(callback) {\n", + " if (callback != null)\n", + " callback();\n", + " });\n", + " } finally {\n", + " delete root._bokeh_onload_callbacks\n", + " }\n", + " console.debug(\"Bokeh: all callbacks have finished\");\n", + " }\n", + "\n", + " function load_libs(css_urls, js_urls, callback) {\n", + " if (css_urls == null) css_urls = [];\n", + " if (js_urls == null) js_urls = [];\n", + "\n", + " root._bokeh_onload_callbacks.push(callback);\n", + " if (root._bokeh_is_loading > 0) {\n", + " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", + " return null;\n", + " }\n", + " if (js_urls == null || js_urls.length === 0) {\n", + " run_callbacks();\n", + " return null;\n", + " }\n", + " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", + " root._bokeh_is_loading = css_urls.length + js_urls.length;\n", + "\n", + " function on_load() {\n", + " root._bokeh_is_loading--;\n", + " if (root._bokeh_is_loading === 0) {\n", + " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", + " run_callbacks()\n", + " }\n", + " }\n", + "\n", + " function on_error() {\n", + " console.error(\"failed to load \" + url);\n", + " }\n", + "\n", + " for (var i = 0; i < css_urls.length; i++) {\n", + " var url = css_urls[i];\n", + " const element = document.createElement(\"link\");\n", + " element.onload = on_load;\n", + " element.onerror = on_error;\n", + " element.rel = \"stylesheet\";\n", + " element.type = \"text/css\";\n", + " element.href = url;\n", + " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", + " document.body.appendChild(element);\n", + " }\n", + "\n", + " for (var i = 0; i < js_urls.length; i++) {\n", + " var url = js_urls[i];\n", + " var element = document.createElement('script');\n", + " element.onload = on_load;\n", + " element.onerror = on_error;\n", + " element.async = false;\n", + " element.src = url;\n", + " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", + " document.head.appendChild(element);\n", + " }\n", + " };var element = document.getElementById(\"4897\");\n", + " if (element == null) {\n", + " console.error(\"Bokeh: ERROR: autoload.js configured with elementid '4897' but no matching script tag was found. \")\n", + " return false;\n", + " }\n", + "\n", + " function inject_raw_css(css) {\n", + " const element = document.createElement(\"style\");\n", + " element.appendChild(document.createTextNode(css));\n", + " document.body.appendChild(element);\n", + " }\n", + "\n", + " var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.1.0.min.js\"];\n", + " var css_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.css\"];\n", + "\n", + " var inline_js = [\n", + " function(Bokeh) {\n", + " Bokeh.set_log_level(\"info\");\n", + " },\n", + " \n", + " function(Bokeh) {\n", + " (function(root, factory) {\n", + " // if(typeof exports === 'object' && typeof module === 'object')\n", + " // factory(require(\"Bokeh\"));\n", + " // else if(typeof define === 'function' && define.amd)\n", + " // define([\"Bokeh\"], factory);\n", + " // else if(typeof exports === 'object')\n", + " // factory(require(\"Bokeh\"));\n", + " // else\n", + " factory(root[\"Bokeh\"]);\n", + " })(this, function(Bokeh) {\n", + " var define;\n", + " return (function outer(modules, entry) {\n", + " if (Bokeh != null) {\n", + " return Bokeh.register_plugin(modules, {}, entry);\n", + " } else {\n", + " throw new Error(\"Cannot find Bokeh. You have to load it prior to loading plugins.\");\n", + " }\n", + " })\n", + " ({\n", + " \"custom/main\": function(require, module, exports) {\n", + " var models = {\n", + " \"ParallelResetTool\": require(\"custom/cave.plot.parallel_plot.parallel_reset.parallel_reset_tool\").ParallelResetTool,\n", + " \"ParallelSelectionTool\": require(\"custom/cave.plot.parallel_plot.parallel_selection_tool.parallel_selection_tool\").ParallelSelectionTool\n", + " };\n", + " require(\"base\").register_models(models);\n", + " module.exports = models;\n", + " },\n", + " \"custom/cave.plot.parallel_plot.parallel_reset.parallel_reset_tool\": function(require, module, exports) {\n", + " \"use strict\";\n", + " var __extends = (this && this.__extends) || (function () {\n", + " var extendStatics = function (d, b) {\n", + " extendStatics = Object.setPrototypeOf ||\n", + " ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n", + " function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n", + " return extendStatics(d, b);\n", + " };\n", + " return function (d, b) {\n", + " extendStatics(d, b);\n", + " function __() { this.constructor = d; }\n", + " d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n", + " };\n", + " })();\n", + " Object.defineProperty(exports, \"__esModule\", { value: true });\n", + " var action_tool_1 = require(\"models/tools/actions/action_tool\");\n", + " var ParallelResetToolView = /** @class */ (function (_super) {\n", + " __extends(ParallelResetToolView, _super);\n", + " function ParallelResetToolView() {\n", + " return _super !== null && _super.apply(this, arguments) || this;\n", + " }\n", + " ParallelResetToolView.prototype.doit = function () {\n", + " this.plot_view.reset_range();\n", + " };\n", + " return ParallelResetToolView;\n", + " }(action_tool_1.ActionToolView));\n", + " exports.ParallelResetToolView = ParallelResetToolView;\n", + " var ParallelResetTool = /** @class */ (function (_super) {\n", + " __extends(ParallelResetTool, _super);\n", + " function ParallelResetTool(attrs) {\n", + " var _this = _super.call(this, attrs) || this;\n", + " _this.tool_name = \"Reset Zoom\";\n", + " _this.icon = \"bk-tool-icon-reset\";\n", + " return _this;\n", + " }\n", + " ParallelResetTool.initClass = function () {\n", + " this.prototype.type = \"ParallelResetTool\";\n", + " this.prototype.default_view = ParallelResetToolView;\n", + " };\n", + " return ParallelResetTool;\n", + " }(action_tool_1.ActionTool));\n", + " exports.ParallelResetTool = ParallelResetTool;\n", + " ParallelResetTool.initClass();\n", + "\n", + " },\n", + " \"custom/cave.plot.parallel_plot.parallel_selection_tool.parallel_selection_tool\": function(require, module, exports) {\n", + " \"use strict\";\n", + " var __extends = (this && this.__extends) || (function () {\n", + " var extendStatics = function (d, b) {\n", + " extendStatics = Object.setPrototypeOf ||\n", + " ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n", + " function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n", + " return extendStatics(d, b);\n", + " };\n", + " return function (d, b) {\n", + " extendStatics(d, b);\n", + " function __() { this.constructor = d; }\n", + " d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n", + " };\n", + " })();\n", + " Object.defineProperty(exports, \"__esModule\", { value: true });\n", + " var p = require(\"core/properties\");\n", + " var box_select_tool_1 = require(\"models/tools/gestures/box_select_tool\");\n", + " var array_1 = require(\"core/util/array\");\n", + " var dom_1 = require(\"core/dom\");\n", + " function find_indices_in(array, _a) {\n", + " var inf = _a[0], sup = _a[1];\n", + " return array.reduce(function (prev, curr, index) {\n", + " return (inf <= curr && curr <= sup) ? prev.concat(index) : prev;\n", + " }, []);\n", + " }\n", + " function index_array(array, indices) {\n", + " return indices.reduce(function (a, i) { return a.concat(array[i]); }, []);\n", + " }\n", + " function combineByKey(key, array) {\n", + " var keys = Object.keys(array[0]);\n", + " var combined = [];\n", + " array.forEach(function (itm) {\n", + " var idx = combined.map(function (item) { return item[key]; }).indexOf(itm[key]);\n", + " if (idx >= 0) {\n", + " keys.forEach(function (element) {\n", + " if (element != key)\n", + " combined[idx][element].push(itm[element]);\n", + " });\n", + " }\n", + " else {\n", + " var new_object_1 = {};\n", + " keys.forEach(function (element) {\n", + " if (element == key) {\n", + " new_object_1[element] = itm[element];\n", + " }\n", + " else {\n", + " new_object_1[element] = [itm[element]];\n", + " }\n", + " });\n", + " combined.push(new_object_1);\n", + " }\n", + " });\n", + " return combined;\n", + " }\n", + " var ParallelSelectionView = /** @class */ (function (_super) {\n", + " __extends(ParallelSelectionView, _super);\n", + " function ParallelSelectionView() {\n", + " var _this = _super !== null && _super.apply(this, arguments) || this;\n", + " _this.selection_mode = \"add\";\n", + " _this.panning = false;\n", + " return _this;\n", + " }\n", + " ParallelSelectionView.prototype.initialize = function () {\n", + " var _this = this;\n", + " _super.prototype.initialize.call(this);\n", + " var frame = this.plot_view.frame;\n", + " var _a = this.model.renderer_select, x_range_name_select = _a.x_range_name, y_range_name_select = _a.y_range_name;\n", + " var _b = this.model.renderer_data, x_range_name_data = _b.x_range_name, y_range_name_data = _b.y_range_name;\n", + " if (x_range_name_select == x_range_name_data && y_range_name_select == y_range_name_data) {\n", + " this.xscale = frame.xscales[x_range_name_select];\n", + " this.yscale = frame.yscales[y_range_name_select];\n", + " }\n", + " else\n", + " throw new Error(\"selection and data does not share the same ranges\");\n", + " //TODO test if parallel CDS is valid (xs for each line should be identical)\n", + " this.glyph_select = this.model.renderer_select.glyph;\n", + " this.glyph_data = this.model.renderer_data.glyph;\n", + " this.cds_select = this.model.renderer_select.data_source;\n", + " this.cds_data = this.model.renderer_data.data_source;\n", + " var _c = [this.glyph_data.xs.field, this.glyph_data.ys.field], xskey = _c[0], yskey = _c[1];\n", + " this.xdata = this.cds_data.get_array(xskey)[0];\n", + " this.ydataT = array_1.transpose(this.cds_data.get_array(yskey));\n", + " this.selection_indices = [];\n", + " this.connect(this.plot_view.frame.x_ranges[this.model.renderer_select.x_range_name].change, function () { return _this._resize_boxes_on_zoom(); });\n", + " this.connect(this.cds_select.change, function () { return _this._update_data_selection(); });\n", + " };\n", + " Object.defineProperty(ParallelSelectionView.prototype, \"_box_width\", {\n", + " get: function () {\n", + " return this.xscale.invert(this.model.box_width) - this.xscale.invert(0);\n", + " },\n", + " enumerable: true,\n", + " configurable: true\n", + " });\n", + " Object.defineProperty(ParallelSelectionView.prototype, \"_cds_select_keys\", {\n", + " get: function () {\n", + " var glyph_select = this.glyph_select;\n", + " var _a = [glyph_select.x.field, glyph_select.y.field], xkey = _a[0], ykey = _a[1];\n", + " var _b = [glyph_select.width.field, glyph_select.height.field], wkey = _b[0], hkey = _b[1];\n", + " return { xkey: xkey, ykey: ykey, wkey: wkey, hkey: hkey };\n", + " },\n", + " enumerable: true,\n", + " configurable: true\n", + " });\n", + " ParallelSelectionView.prototype._emit_cds_changes = function (cds, redraw, clear, emit) {\n", + " if (redraw === void 0) { redraw = true; }\n", + " if (clear === void 0) { clear = true; }\n", + " if (emit === void 0) { emit = true; }\n", + " if (clear)\n", + " cds.selection_manager.clear();\n", + " if (redraw)\n", + " cds.change.emit();\n", + " if (emit) {\n", + " cds.data = cds.data;\n", + " cds.properties.data.change.emit();\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._box_paramaters = function (index) {\n", + " var _a = this._cds_select_keys, xkey = _a.xkey, ykey = _a.ykey, wkey = _a.wkey, hkey = _a.hkey;\n", + " var x = this.cds_select.get_array(xkey)[index];\n", + " var y = this.cds_select.get_array(ykey)[index];\n", + " var w = this.cds_select.get_array(wkey)[index];\n", + " var h = this.cds_select.get_array(hkey)[index];\n", + " return { x: x, y: y, w: w, h: h };\n", + " };\n", + " ParallelSelectionView.prototype._hit_test_boxes = function (sx, sy) {\n", + " var nboxes = this.cds_select.get_length();\n", + " if (nboxes != 0 && nboxes != null) {\n", + " var _a = [this.xscale.invert(sx), this.yscale.invert(sy)], xtest = _a[0], ytest = _a[1];\n", + " for (var i = 0; i < nboxes; i++) {\n", + " var _b = this._box_paramaters(i), x = _b.x, y = _b.y, w = _b.w, h = _b.h;\n", + " if (xtest >= (x - w / 2) && xtest <= x + w / 2 &&\n", + " ytest >= (y - h / 2) && ytest <= y + h / 2) {\n", + " return i;\n", + " }\n", + " }\n", + " }\n", + " return null;\n", + " };\n", + " ParallelSelectionView.prototype._resize_boxes_on_zoom = function () {\n", + " //resize selection boxes when zooming to keep a constant (pixel) size\n", + " var cds = this.cds_select;\n", + " var array_width = cds.get_array(this.glyph_select.width.field);\n", + " var new_width = this._box_width;\n", + " array_width.forEach(function (_, i) { return array_width[i] = new_width; });\n", + " this._emit_cds_changes(cds, true, false, false);\n", + " };\n", + " ParallelSelectionView.prototype._drag_start = function (ev) {\n", + " //Save y position of the drag start\n", + " if (this.ind_active_box != null) {\n", + " this._base_point = [this.xscale.invert(ev.sx), this.yscale.invert(ev.sy)];\n", + " this._base_box_parameters = this._box_paramaters(this.ind_active_box);\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._update_box_ypos = function (index_box, delta_y) {\n", + " if (this._base_box_parameters != null) {\n", + " var cds = this.cds_select;\n", + " var ykey = this._cds_select_keys.ykey;\n", + " var _a = this._base_box_parameters, current_y = _a.y, h = _a.h;\n", + " var new_y = current_y + delta_y;\n", + " new_y = new_y - Math.max(0, (new_y + h / 2) - 1) - Math.min(0, (new_y - h / 2));\n", + " cds.get_array(ykey)[index_box] = new_y;\n", + " this._emit_cds_changes(cds, true, false, false);\n", + " this._update_selection_indices(index_box, [new_y - h / 2, new_y + h / 2]);\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._drag = function (ev) {\n", + " if (this.ind_active_box != null && this._base_point != null) {\n", + " var delta_y = this.yscale.invert(ev.sy) - this._base_point[1];\n", + " this._update_box_ypos(this.ind_active_box, delta_y);\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._drag_stop = function (_ev) {\n", + " this._base_point = null;\n", + " this._base_box_parameters = null;\n", + " };\n", + " ParallelSelectionView.prototype._pan_start = function (ev) {\n", + " this.panning = true;\n", + " switch (this.selection_mode) {\n", + " case \"add\": {\n", + " _super.prototype._pan_start.call(this, ev);\n", + " break;\n", + " }\n", + " case \"drag\": {\n", + " this._drag_start(ev);\n", + " break;\n", + " }\n", + " case \"resize\": {\n", + " break;\n", + " }\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._pan = function (ev) {\n", + " switch (this.selection_mode) {\n", + " case \"add\": {\n", + " _super.prototype._pan.call(this, ev);\n", + " break;\n", + " }\n", + " case \"drag\": {\n", + " this._drag(ev);\n", + " break;\n", + " }\n", + " case \"resize\": {\n", + " break;\n", + " }\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._pan_end = function (ev) {\n", + " switch (this.selection_mode) {\n", + " case \"add\": {\n", + " _super.prototype._pan_end.call(this, ev);\n", + " break;\n", + " }\n", + " case \"drag\": {\n", + " this._drag_stop(ev);\n", + " break;\n", + " }\n", + " case \"resize\": {\n", + " break;\n", + " }\n", + " }\n", + " this.panning = false;\n", + " };\n", + " ParallelSelectionView.prototype._move = function (ev) {\n", + " //Switch mode\n", + " if (this.panning) {\n", + " return;\n", + " }\n", + " this.ind_active_box = this._hit_test_boxes(ev.sx, ev.sy);\n", + " if (this.ind_active_box != null) {\n", + " this.selection_mode = \"drag\";\n", + " }\n", + " else {\n", + " this.selection_mode = \"add\";\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._doubletap = function (_ev) {\n", + " var _this = this;\n", + " //delete box on double tap\n", + " if (this.ind_active_box != null) {\n", + " this.cds_select.columns().forEach(function (key) {\n", + " _this.cds_select.get_array(key).splice(_this.ind_active_box, 1);\n", + " });\n", + " this._delete_selection_indices(this.ind_active_box);\n", + " this._emit_cds_changes(this.cds_select);\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._keyup = function (ev) {\n", + " var _this = this;\n", + " if (ev.keyCode == dom_1.Keys.Esc) {\n", + " var nelems_1 = this.cds_select.get_length();\n", + " if (nelems_1 != null) {\n", + " this.cds_select.columns().forEach(function (key) {\n", + " _this.cds_select.get_array(key).splice(0, nelems_1);\n", + " });\n", + " this.selection_indices.splice(0, nelems_1);\n", + " this._emit_cds_changes(this.cds_select);\n", + " }\n", + " this.plot_view.request_render();\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._update_data_selection = function () {\n", + " var selection_indices = [];\n", + " if (this.selection_indices.length > 0) {\n", + " var combined_selections = combineByKey('data_idx', this.selection_indices);\n", + " selection_indices = array_1.intersection.apply(void 0, [array_1.union.apply(void 0, combined_selections[0].indices)].concat(combined_selections.slice(1).map(function (elem) { return array_1.union.apply(void 0, elem.indices); })));\n", + " }\n", + " this.cds_data.selected.indices = selection_indices;\n", + " this.cds_data.change.emit();\n", + " };\n", + " ParallelSelectionView.prototype._make_selection_indices = function (indices, _a) {\n", + " var _this = this;\n", + " var _b;\n", + " var y0 = _a[0], y1 = _a[1];\n", + " (_b = this.selection_indices).push.apply(_b, indices.map(function (index) {\n", + " return {\n", + " data_idx: index,\n", + " indices: find_indices_in(_this.ydataT[index], [y0, y1]),\n", + " };\n", + " }));\n", + " };\n", + " ParallelSelectionView.prototype._update_selection_indices = function (index, _a) {\n", + " var y0 = _a[0], y1 = _a[1];\n", + " this.selection_indices[index].indices = find_indices_in(this.ydataT[this.selection_indices[index].data_idx], [y0, y1]);\n", + " };\n", + " ParallelSelectionView.prototype._delete_selection_indices = function (index) {\n", + " this.selection_indices.splice(index, 1);\n", + " };\n", + " ParallelSelectionView.prototype._make_box_select = function (xs, _a) {\n", + " var _this = this;\n", + " var y0 = _a[0], y1 = _a[1];\n", + " y0 = Math.max(0, y0);\n", + " y1 = Math.min(1, y1);\n", + " var y = (y0 + y1) / 2.;\n", + " var w = this._box_width;\n", + " var h = y1 - y0;\n", + " var _b = this._cds_select_keys, xkey = _b.xkey, ykey = _b.ykey, wkey = _b.wkey, hkey = _b.hkey;\n", + " xs.forEach(function (x) {\n", + " if (xkey)\n", + " _this.cds_select.get_array(xkey).push(x);\n", + " if (ykey)\n", + " _this.cds_select.get_array(ykey).push(y);\n", + " if (wkey)\n", + " _this.cds_select.get_array(wkey).push(w);\n", + " if (hkey)\n", + " _this.cds_select.get_array(hkey).push(h);\n", + " });\n", + " this._emit_cds_changes(this.cds_select);\n", + " };\n", + " ParallelSelectionView.prototype._do_select = function (_a, _b, _final, _append) {\n", + " var sx0 = _a[0], sx1 = _a[1];\n", + " var sy0 = _b[0], sy1 = _b[1];\n", + " if (_final === void 0) { _final = true; }\n", + " if (_append === void 0) { _append = true; }\n", + " // Get selection bbox in the data space\n", + " var _c = this.xscale.r_invert(sx0, sx1), x0 = _c[0], x1 = _c[1];\n", + " var _d = this.yscale.r_invert(sy0, sy1), y0 = _d[0], y1 = _d[1];\n", + " var x_indices = find_indices_in(this.xdata, [x0, x1]);\n", + " var xs = index_array(this.xdata, x_indices);\n", + " this._make_selection_indices(x_indices, [y0, y1]);\n", + " this._make_box_select(xs, [y0, y1]);\n", + " };\n", + " return ParallelSelectionView;\n", + " }(box_select_tool_1.BoxSelectToolView));\n", + " exports.ParallelSelectionView = ParallelSelectionView;\n", + " var ParallelSelectionTool = /** @class */ (function (_super) {\n", + " __extends(ParallelSelectionTool, _super);\n", + " function ParallelSelectionTool() {\n", + " var _this = _super !== null && _super.apply(this, arguments) || this;\n", + " _this.tool_name = \"Parallel Selection\";\n", + " //override event_type property define in BoxSelectTool\n", + " _this.event_type = [\"tap\", \"pan\", \"move\"];\n", + " return _this;\n", + " }\n", + " ParallelSelectionTool.initClass = function () {\n", + " this.prototype.type = \"ParallelSelectionTool\";\n", + " this.prototype.default_view = ParallelSelectionView;\n", + " this.define({\n", + " renderer_select: [p.Any],\n", + " renderer_data: [p.Any],\n", + " box_width: [p.Number, 30],\n", + " });\n", + " };\n", + " return ParallelSelectionTool;\n", + " }(box_select_tool_1.BoxSelectTool));\n", + " exports.ParallelSelectionTool = ParallelSelectionTool;\n", + " ParallelSelectionTool.initClass();\n", + "\n", + " }\n", + " }, \"custom/main\");\n", + " ;\n", + " });\n", + "\n", + " },\n", + " function(Bokeh) {} // ensure no trailing comma for IE\n", + " ];\n", + "\n", + " function run_inline_js() {\n", + " \n", + " if ((root.Bokeh !== undefined) || (force === true)) {\n", + " for (var i = 0; i < inline_js.length; i++) {\n", + " inline_js[i].call(root, root.Bokeh);\n", + " }if (force === true) {\n", + " display_loaded();\n", + " }} else if (Date.now() < root._bokeh_timeout) {\n", + " setTimeout(run_inline_js, 100);\n", + " } else if (!root._bokeh_failed_load) {\n", + " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", + " root._bokeh_failed_load = true;\n", + " } else if (force !== true) {\n", + " var cell = $(document.getElementById(\"4897\")).parents('.cell').data().cell;\n", + " cell.output_area.append_execute_result(NB_LOAD_WARNING)\n", + " }\n", + "\n", + " }\n", + "\n", + " if (root._bokeh_is_loading === 0) {\n", + " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", + " run_inline_js();\n", + " } else {\n", + " load_libs(css_urls, js_urls, function() {\n", + " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", + " run_inline_js();\n", + " });\n", + " }\n", + "}(window));" + ], + "application/vnd.bokehjs_load.v0+json": "\n(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n \n\n \n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n var NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n var el = document.getElementById(\"4897\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };var element = document.getElementById(\"4897\");\n if (element == null) {\n console.error(\"Bokeh: ERROR: autoload.js configured with elementid '4897' but no matching script tag was found. \")\n return false;\n }\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.1.0.min.js\"];\n var css_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.css\"];\n\n var inline_js = [\n function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n \n function(Bokeh) {\n (function(root, factory) {\n // if(typeof exports === 'object' && typeof module === 'object')\n // factory(require(\"Bokeh\"));\n // else if(typeof define === 'function' && define.amd)\n // define([\"Bokeh\"], factory);\n // else if(typeof exports === 'object')\n // factory(require(\"Bokeh\"));\n // else\n factory(root[\"Bokeh\"]);\n })(this, function(Bokeh) {\n var define;\n return (function outer(modules, entry) {\n if (Bokeh != null) {\n return Bokeh.register_plugin(modules, {}, entry);\n } else {\n throw new Error(\"Cannot find Bokeh. You have to load it prior to loading plugins.\");\n }\n })\n ({\n \"custom/main\": function(require, module, exports) {\n var models = {\n \"ParallelResetTool\": require(\"custom/cave.plot.parallel_plot.parallel_reset.parallel_reset_tool\").ParallelResetTool,\n \"ParallelSelectionTool\": require(\"custom/cave.plot.parallel_plot.parallel_selection_tool.parallel_selection_tool\").ParallelSelectionTool\n };\n require(\"base\").register_models(models);\n module.exports = models;\n },\n \"custom/cave.plot.parallel_plot.parallel_reset.parallel_reset_tool\": function(require, module, exports) {\n \"use strict\";\n var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n })();\n Object.defineProperty(exports, \"__esModule\", { value: true });\n var action_tool_1 = require(\"models/tools/actions/action_tool\");\n var ParallelResetToolView = /** @class */ (function (_super) {\n __extends(ParallelResetToolView, _super);\n function ParallelResetToolView() {\n return _super !== null && _super.apply(this, arguments) || this;\n }\n ParallelResetToolView.prototype.doit = function () {\n this.plot_view.reset_range();\n };\n return ParallelResetToolView;\n }(action_tool_1.ActionToolView));\n exports.ParallelResetToolView = ParallelResetToolView;\n var ParallelResetTool = /** @class */ (function (_super) {\n __extends(ParallelResetTool, _super);\n function ParallelResetTool(attrs) {\n var _this = _super.call(this, attrs) || this;\n _this.tool_name = \"Reset Zoom\";\n _this.icon = \"bk-tool-icon-reset\";\n return _this;\n }\n ParallelResetTool.initClass = function () {\n this.prototype.type = \"ParallelResetTool\";\n this.prototype.default_view = ParallelResetToolView;\n };\n return ParallelResetTool;\n }(action_tool_1.ActionTool));\n exports.ParallelResetTool = ParallelResetTool;\n ParallelResetTool.initClass();\n\n },\n \"custom/cave.plot.parallel_plot.parallel_selection_tool.parallel_selection_tool\": function(require, module, exports) {\n \"use strict\";\n var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n })();\n Object.defineProperty(exports, \"__esModule\", { value: true });\n var p = require(\"core/properties\");\n var box_select_tool_1 = require(\"models/tools/gestures/box_select_tool\");\n var array_1 = require(\"core/util/array\");\n var dom_1 = require(\"core/dom\");\n function find_indices_in(array, _a) {\n var inf = _a[0], sup = _a[1];\n return array.reduce(function (prev, curr, index) {\n return (inf <= curr && curr <= sup) ? prev.concat(index) : prev;\n }, []);\n }\n function index_array(array, indices) {\n return indices.reduce(function (a, i) { return a.concat(array[i]); }, []);\n }\n function combineByKey(key, array) {\n var keys = Object.keys(array[0]);\n var combined = [];\n array.forEach(function (itm) {\n var idx = combined.map(function (item) { return item[key]; }).indexOf(itm[key]);\n if (idx >= 0) {\n keys.forEach(function (element) {\n if (element != key)\n combined[idx][element].push(itm[element]);\n });\n }\n else {\n var new_object_1 = {};\n keys.forEach(function (element) {\n if (element == key) {\n new_object_1[element] = itm[element];\n }\n else {\n new_object_1[element] = [itm[element]];\n }\n });\n combined.push(new_object_1);\n }\n });\n return combined;\n }\n var ParallelSelectionView = /** @class */ (function (_super) {\n __extends(ParallelSelectionView, _super);\n function ParallelSelectionView() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n _this.selection_mode = \"add\";\n _this.panning = false;\n return _this;\n }\n ParallelSelectionView.prototype.initialize = function () {\n var _this = this;\n _super.prototype.initialize.call(this);\n var frame = this.plot_view.frame;\n var _a = this.model.renderer_select, x_range_name_select = _a.x_range_name, y_range_name_select = _a.y_range_name;\n var _b = this.model.renderer_data, x_range_name_data = _b.x_range_name, y_range_name_data = _b.y_range_name;\n if (x_range_name_select == x_range_name_data && y_range_name_select == y_range_name_data) {\n this.xscale = frame.xscales[x_range_name_select];\n this.yscale = frame.yscales[y_range_name_select];\n }\n else\n throw new Error(\"selection and data does not share the same ranges\");\n //TODO test if parallel CDS is valid (xs for each line should be identical)\n this.glyph_select = this.model.renderer_select.glyph;\n this.glyph_data = this.model.renderer_data.glyph;\n this.cds_select = this.model.renderer_select.data_source;\n this.cds_data = this.model.renderer_data.data_source;\n var _c = [this.glyph_data.xs.field, this.glyph_data.ys.field], xskey = _c[0], yskey = _c[1];\n this.xdata = this.cds_data.get_array(xskey)[0];\n this.ydataT = array_1.transpose(this.cds_data.get_array(yskey));\n this.selection_indices = [];\n this.connect(this.plot_view.frame.x_ranges[this.model.renderer_select.x_range_name].change, function () { return _this._resize_boxes_on_zoom(); });\n this.connect(this.cds_select.change, function () { return _this._update_data_selection(); });\n };\n Object.defineProperty(ParallelSelectionView.prototype, \"_box_width\", {\n get: function () {\n return this.xscale.invert(this.model.box_width) - this.xscale.invert(0);\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(ParallelSelectionView.prototype, \"_cds_select_keys\", {\n get: function () {\n var glyph_select = this.glyph_select;\n var _a = [glyph_select.x.field, glyph_select.y.field], xkey = _a[0], ykey = _a[1];\n var _b = [glyph_select.width.field, glyph_select.height.field], wkey = _b[0], hkey = _b[1];\n return { xkey: xkey, ykey: ykey, wkey: wkey, hkey: hkey };\n },\n enumerable: true,\n configurable: true\n });\n ParallelSelectionView.prototype._emit_cds_changes = function (cds, redraw, clear, emit) {\n if (redraw === void 0) { redraw = true; }\n if (clear === void 0) { clear = true; }\n if (emit === void 0) { emit = true; }\n if (clear)\n cds.selection_manager.clear();\n if (redraw)\n cds.change.emit();\n if (emit) {\n cds.data = cds.data;\n cds.properties.data.change.emit();\n }\n };\n ParallelSelectionView.prototype._box_paramaters = function (index) {\n var _a = this._cds_select_keys, xkey = _a.xkey, ykey = _a.ykey, wkey = _a.wkey, hkey = _a.hkey;\n var x = this.cds_select.get_array(xkey)[index];\n var y = this.cds_select.get_array(ykey)[index];\n var w = this.cds_select.get_array(wkey)[index];\n var h = this.cds_select.get_array(hkey)[index];\n return { x: x, y: y, w: w, h: h };\n };\n ParallelSelectionView.prototype._hit_test_boxes = function (sx, sy) {\n var nboxes = this.cds_select.get_length();\n if (nboxes != 0 && nboxes != null) {\n var _a = [this.xscale.invert(sx), this.yscale.invert(sy)], xtest = _a[0], ytest = _a[1];\n for (var i = 0; i < nboxes; i++) {\n var _b = this._box_paramaters(i), x = _b.x, y = _b.y, w = _b.w, h = _b.h;\n if (xtest >= (x - w / 2) && xtest <= x + w / 2 &&\n ytest >= (y - h / 2) && ytest <= y + h / 2) {\n return i;\n }\n }\n }\n return null;\n };\n ParallelSelectionView.prototype._resize_boxes_on_zoom = function () {\n //resize selection boxes when zooming to keep a constant (pixel) size\n var cds = this.cds_select;\n var array_width = cds.get_array(this.glyph_select.width.field);\n var new_width = this._box_width;\n array_width.forEach(function (_, i) { return array_width[i] = new_width; });\n this._emit_cds_changes(cds, true, false, false);\n };\n ParallelSelectionView.prototype._drag_start = function (ev) {\n //Save y position of the drag start\n if (this.ind_active_box != null) {\n this._base_point = [this.xscale.invert(ev.sx), this.yscale.invert(ev.sy)];\n this._base_box_parameters = this._box_paramaters(this.ind_active_box);\n }\n };\n ParallelSelectionView.prototype._update_box_ypos = function (index_box, delta_y) {\n if (this._base_box_parameters != null) {\n var cds = this.cds_select;\n var ykey = this._cds_select_keys.ykey;\n var _a = this._base_box_parameters, current_y = _a.y, h = _a.h;\n var new_y = current_y + delta_y;\n new_y = new_y - Math.max(0, (new_y + h / 2) - 1) - Math.min(0, (new_y - h / 2));\n cds.get_array(ykey)[index_box] = new_y;\n this._emit_cds_changes(cds, true, false, false);\n this._update_selection_indices(index_box, [new_y - h / 2, new_y + h / 2]);\n }\n };\n ParallelSelectionView.prototype._drag = function (ev) {\n if (this.ind_active_box != null && this._base_point != null) {\n var delta_y = this.yscale.invert(ev.sy) - this._base_point[1];\n this._update_box_ypos(this.ind_active_box, delta_y);\n }\n };\n ParallelSelectionView.prototype._drag_stop = function (_ev) {\n this._base_point = null;\n this._base_box_parameters = null;\n };\n ParallelSelectionView.prototype._pan_start = function (ev) {\n this.panning = true;\n switch (this.selection_mode) {\n case \"add\": {\n _super.prototype._pan_start.call(this, ev);\n break;\n }\n case \"drag\": {\n this._drag_start(ev);\n break;\n }\n case \"resize\": {\n break;\n }\n }\n };\n ParallelSelectionView.prototype._pan = function (ev) {\n switch (this.selection_mode) {\n case \"add\": {\n _super.prototype._pan.call(this, ev);\n break;\n }\n case \"drag\": {\n this._drag(ev);\n break;\n }\n case \"resize\": {\n break;\n }\n }\n };\n ParallelSelectionView.prototype._pan_end = function (ev) {\n switch (this.selection_mode) {\n case \"add\": {\n _super.prototype._pan_end.call(this, ev);\n break;\n }\n case \"drag\": {\n this._drag_stop(ev);\n break;\n }\n case \"resize\": {\n break;\n }\n }\n this.panning = false;\n };\n ParallelSelectionView.prototype._move = function (ev) {\n //Switch mode\n if (this.panning) {\n return;\n }\n this.ind_active_box = this._hit_test_boxes(ev.sx, ev.sy);\n if (this.ind_active_box != null) {\n this.selection_mode = \"drag\";\n }\n else {\n this.selection_mode = \"add\";\n }\n };\n ParallelSelectionView.prototype._doubletap = function (_ev) {\n var _this = this;\n //delete box on double tap\n if (this.ind_active_box != null) {\n this.cds_select.columns().forEach(function (key) {\n _this.cds_select.get_array(key).splice(_this.ind_active_box, 1);\n });\n this._delete_selection_indices(this.ind_active_box);\n this._emit_cds_changes(this.cds_select);\n }\n };\n ParallelSelectionView.prototype._keyup = function (ev) {\n var _this = this;\n if (ev.keyCode == dom_1.Keys.Esc) {\n var nelems_1 = this.cds_select.get_length();\n if (nelems_1 != null) {\n this.cds_select.columns().forEach(function (key) {\n _this.cds_select.get_array(key).splice(0, nelems_1);\n });\n this.selection_indices.splice(0, nelems_1);\n this._emit_cds_changes(this.cds_select);\n }\n this.plot_view.request_render();\n }\n };\n ParallelSelectionView.prototype._update_data_selection = function () {\n var selection_indices = [];\n if (this.selection_indices.length > 0) {\n var combined_selections = combineByKey('data_idx', this.selection_indices);\n selection_indices = array_1.intersection.apply(void 0, [array_1.union.apply(void 0, combined_selections[0].indices)].concat(combined_selections.slice(1).map(function (elem) { return array_1.union.apply(void 0, elem.indices); })));\n }\n this.cds_data.selected.indices = selection_indices;\n this.cds_data.change.emit();\n };\n ParallelSelectionView.prototype._make_selection_indices = function (indices, _a) {\n var _this = this;\n var _b;\n var y0 = _a[0], y1 = _a[1];\n (_b = this.selection_indices).push.apply(_b, indices.map(function (index) {\n return {\n data_idx: index,\n indices: find_indices_in(_this.ydataT[index], [y0, y1]),\n };\n }));\n };\n ParallelSelectionView.prototype._update_selection_indices = function (index, _a) {\n var y0 = _a[0], y1 = _a[1];\n this.selection_indices[index].indices = find_indices_in(this.ydataT[this.selection_indices[index].data_idx], [y0, y1]);\n };\n ParallelSelectionView.prototype._delete_selection_indices = function (index) {\n this.selection_indices.splice(index, 1);\n };\n ParallelSelectionView.prototype._make_box_select = function (xs, _a) {\n var _this = this;\n var y0 = _a[0], y1 = _a[1];\n y0 = Math.max(0, y0);\n y1 = Math.min(1, y1);\n var y = (y0 + y1) / 2.;\n var w = this._box_width;\n var h = y1 - y0;\n var _b = this._cds_select_keys, xkey = _b.xkey, ykey = _b.ykey, wkey = _b.wkey, hkey = _b.hkey;\n xs.forEach(function (x) {\n if (xkey)\n _this.cds_select.get_array(xkey).push(x);\n if (ykey)\n _this.cds_select.get_array(ykey).push(y);\n if (wkey)\n _this.cds_select.get_array(wkey).push(w);\n if (hkey)\n _this.cds_select.get_array(hkey).push(h);\n });\n this._emit_cds_changes(this.cds_select);\n };\n ParallelSelectionView.prototype._do_select = function (_a, _b, _final, _append) {\n var sx0 = _a[0], sx1 = _a[1];\n var sy0 = _b[0], sy1 = _b[1];\n if (_final === void 0) { _final = true; }\n if (_append === void 0) { _append = true; }\n // Get selection bbox in the data space\n var _c = this.xscale.r_invert(sx0, sx1), x0 = _c[0], x1 = _c[1];\n var _d = this.yscale.r_invert(sy0, sy1), y0 = _d[0], y1 = _d[1];\n var x_indices = find_indices_in(this.xdata, [x0, x1]);\n var xs = index_array(this.xdata, x_indices);\n this._make_selection_indices(x_indices, [y0, y1]);\n this._make_box_select(xs, [y0, y1]);\n };\n return ParallelSelectionView;\n }(box_select_tool_1.BoxSelectToolView));\n exports.ParallelSelectionView = ParallelSelectionView;\n var ParallelSelectionTool = /** @class */ (function (_super) {\n __extends(ParallelSelectionTool, _super);\n function ParallelSelectionTool() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n _this.tool_name = \"Parallel Selection\";\n //override event_type property define in BoxSelectTool\n _this.event_type = [\"tap\", \"pan\", \"move\"];\n return _this;\n }\n ParallelSelectionTool.initClass = function () {\n this.prototype.type = \"ParallelSelectionTool\";\n this.prototype.default_view = ParallelSelectionView;\n this.define({\n renderer_select: [p.Any],\n renderer_data: [p.Any],\n box_width: [p.Number, 30],\n });\n };\n return ParallelSelectionTool;\n }(box_select_tool_1.BoxSelectTool));\n exports.ParallelSelectionTool = ParallelSelectionTool;\n ParallelSelectionTool.initClass();\n\n }\n }, \"custom/main\");\n ;\n });\n\n },\n function(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n \n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }if (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n var cell = $(document.getElementById(\"4897\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "(function(root) {\n", + " function embed_document(root) {\n", + " \n", + " var docs_json = {\"06bbb144-6c77-4643-bce0-9a725c3d0ad9\":{\"roots\":{\"references\":[{\"attributes\":{\"children\":[{\"id\":\"4566\",\"type\":\"Column\"},{\"id\":\"4574\",\"type\":\"Column\"}]},\"id\":\"4575\",\"type\":\"Row\"},{\"attributes\":{},\"id\":\"1032\",\"type\":\"WheelZoomTool\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"1084\",\"type\":\"GroupFilter\"},{\"attributes\":{\"high\":-11.644708333333334,\"low\":-77.62476166666667,\"palette\":[\"#440154\",\"#440255\",\"#440357\",\"#450558\",\"#45065A\",\"#45085B\",\"#46095C\",\"#460B5E\",\"#460C5F\",\"#460E61\",\"#470F62\",\"#471163\",\"#471265\",\"#471466\",\"#471567\",\"#471669\",\"#47186A\",\"#48196B\",\"#481A6C\",\"#481C6E\",\"#481D6F\",\"#481E70\",\"#482071\",\"#482172\",\"#482273\",\"#482374\",\"#472575\",\"#472676\",\"#472777\",\"#472878\",\"#472A79\",\"#472B7A\",\"#472C7B\",\"#462D7C\",\"#462F7C\",\"#46307D\",\"#46317E\",\"#45327F\",\"#45347F\",\"#453580\",\"#453681\",\"#443781\",\"#443982\",\"#433A83\",\"#433B83\",\"#433C84\",\"#423D84\",\"#423E85\",\"#424085\",\"#414186\",\"#414286\",\"#404387\",\"#404487\",\"#3F4587\",\"#3F4788\",\"#3E4888\",\"#3E4989\",\"#3D4A89\",\"#3D4B89\",\"#3D4C89\",\"#3C4D8A\",\"#3C4E8A\",\"#3B508A\",\"#3B518A\",\"#3A528B\",\"#3A538B\",\"#39548B\",\"#39558B\",\"#38568B\",\"#38578C\",\"#37588C\",\"#37598C\",\"#365A8C\",\"#365B8C\",\"#355C8C\",\"#355D8C\",\"#345E8D\",\"#345F8D\",\"#33608D\",\"#33618D\",\"#32628D\",\"#32638D\",\"#31648D\",\"#31658D\",\"#31668D\",\"#30678D\",\"#30688D\",\"#2F698D\",\"#2F6A8D\",\"#2E6B8E\",\"#2E6C8E\",\"#2E6D8E\",\"#2D6E8E\",\"#2D6F8E\",\"#2C708E\",\"#2C718E\",\"#2C728E\",\"#2B738E\",\"#2B748E\",\"#2A758E\",\"#2A768E\",\"#2A778E\",\"#29788E\",\"#29798E\",\"#287A8E\",\"#287A8E\",\"#287B8E\",\"#277C8E\",\"#277D8E\",\"#277E8E\",\"#267F8E\",\"#26808E\",\"#26818E\",\"#25828E\",\"#25838D\",\"#24848D\",\"#24858D\",\"#24868D\",\"#23878D\",\"#23888D\",\"#23898D\",\"#22898D\",\"#228A8D\",\"#228B8D\",\"#218C8D\",\"#218D8C\",\"#218E8C\",\"#208F8C\",\"#20908C\",\"#20918C\",\"#1F928C\",\"#1F938B\",\"#1F948B\",\"#1F958B\",\"#1F968B\",\"#1E978A\",\"#1E988A\",\"#1E998A\",\"#1E998A\",\"#1E9A89\",\"#1E9B89\",\"#1E9C89\",\"#1E9D88\",\"#1E9E88\",\"#1E9F88\",\"#1EA087\",\"#1FA187\",\"#1FA286\",\"#1FA386\",\"#20A485\",\"#20A585\",\"#21A685\",\"#21A784\",\"#22A784\",\"#23A883\",\"#23A982\",\"#24AA82\",\"#25AB81\",\"#26AC81\",\"#27AD80\",\"#28AE7F\",\"#29AF7F\",\"#2AB07E\",\"#2BB17D\",\"#2CB17D\",\"#2EB27C\",\"#2FB37B\",\"#30B47A\",\"#32B57A\",\"#33B679\",\"#35B778\",\"#36B877\",\"#38B976\",\"#39B976\",\"#3BBA75\",\"#3DBB74\",\"#3EBC73\",\"#40BD72\",\"#42BE71\",\"#44BE70\",\"#45BF6F\",\"#47C06E\",\"#49C16D\",\"#4BC26C\",\"#4DC26B\",\"#4FC369\",\"#51C468\",\"#53C567\",\"#55C666\",\"#57C665\",\"#59C764\",\"#5BC862\",\"#5EC961\",\"#60C960\",\"#62CA5F\",\"#64CB5D\",\"#67CC5C\",\"#69CC5B\",\"#6BCD59\",\"#6DCE58\",\"#70CE56\",\"#72CF55\",\"#74D054\",\"#77D052\",\"#79D151\",\"#7CD24F\",\"#7ED24E\",\"#81D34C\",\"#83D34B\",\"#86D449\",\"#88D547\",\"#8BD546\",\"#8DD644\",\"#90D643\",\"#92D741\",\"#95D73F\",\"#97D83E\",\"#9AD83C\",\"#9DD93A\",\"#9FD938\",\"#A2DA37\",\"#A5DA35\",\"#A7DB33\",\"#AADB32\",\"#ADDC30\",\"#AFDC2E\",\"#B2DD2C\",\"#B5DD2B\",\"#B7DD29\",\"#BADE27\",\"#BDDE26\",\"#BFDF24\",\"#C2DF22\",\"#C5DF21\",\"#C7E01F\",\"#CAE01E\",\"#CDE01D\",\"#CFE11C\",\"#D2E11B\",\"#D4E11A\",\"#D7E219\",\"#DAE218\",\"#DCE218\",\"#DFE318\",\"#E1E318\",\"#E4E318\",\"#E7E419\",\"#E9E419\",\"#ECE41A\",\"#EEE51B\",\"#F1E51C\",\"#F3E51E\",\"#F6E61F\",\"#F8E621\",\"#FAE622\",\"#FDE724\"]},\"id\":\"1040\",\"type\":\"LinearColorMapper\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"1085\",\"type\":\"GroupFilter\"},{\"attributes\":{\"overlay\":{\"id\":\"1169\",\"type\":\"BoxAnnotation\"}},\"id\":\"1031\",\"type\":\"BoxZoomTool\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"2848\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1086\",\"type\":\"GroupFilter\"},{\"attributes\":{},\"id\":\"1030\",\"type\":\"SaveTool\"},{\"attributes\":{\"booleans\":[true,true]},\"id\":\"1087\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1084\",\"type\":\"GroupFilter\"},{\"id\":\"1085\",\"type\":\"GroupFilter\"},{\"id\":\"1086\",\"type\":\"GroupFilter\"},{\"id\":\"1087\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"}},\"id\":\"1088\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"1089\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"1090\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1091\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true]},\"id\":\"1092\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1089\",\"type\":\"GroupFilter\"},{\"id\":\"1090\",\"type\":\"GroupFilter\"},{\"id\":\"1091\",\"type\":\"GroupFilter\"},{\"id\":\"1092\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"}},\"id\":\"1093\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"3631\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"1094\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"1095\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1096\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true]},\"id\":\"1097\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1094\",\"type\":\"GroupFilter\"},{\"id\":\"1095\",\"type\":\"GroupFilter\"},{\"id\":\"1096\",\"type\":\"GroupFilter\"},{\"id\":\"1097\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"}},\"id\":\"1098\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"1099\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"1100\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1101\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"2863\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true]},\"id\":\"1102\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1099\",\"type\":\"GroupFilter\"},{\"id\":\"1100\",\"type\":\"GroupFilter\"},{\"id\":\"1101\",\"type\":\"GroupFilter\"},{\"id\":\"1102\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"}},\"id\":\"1103\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"1104\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2850\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"1105\",\"type\":\"GroupFilter\"},{\"attributes\":{},\"id\":\"1033\",\"type\":\"ResetTool\"},{\"attributes\":{\"filters\":[{\"id\":\"2903\",\"type\":\"GroupFilter\"},{\"id\":\"2904\",\"type\":\"GroupFilter\"},{\"id\":\"2905\",\"type\":\"GroupFilter\"},{\"id\":\"2906\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"}},\"id\":\"2907\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1106\",\"type\":\"GroupFilter\"},{\"attributes\":{\"active_drag\":\"auto\",\"active_inspect\":\"auto\",\"active_multi\":null,\"active_scroll\":\"auto\",\"active_tap\":\"auto\",\"tools\":[{\"id\":\"1030\",\"type\":\"SaveTool\"},{\"id\":\"1031\",\"type\":\"BoxZoomTool\"},{\"id\":\"1032\",\"type\":\"WheelZoomTool\"},{\"id\":\"1033\",\"type\":\"ResetTool\"},{\"id\":\"4552\",\"type\":\"HoverTool\"}]},\"id\":\"1034\",\"type\":\"Toolbar\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"2849\",\"type\":\"GroupFilter\"},{\"attributes\":{\"callback\":null,\"data\":{\"image\":[{\"__ndarray__\":\"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\",\"dtype\":\"float64\",\"shape\":[18,17]},{\"__ndarray__\":\"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\",\"dtype\":\"float64\",\"shape\":[18,17]},{\"__ndarray__\":\"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\",\"dtype\":\"float64\",\"shape\":[18,17]}]},\"selected\":{\"id\":\"1171\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1170\",\"type\":\"UnionRenderers\"}},\"id\":\"1041\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"booleans\":[true,true]},\"id\":\"1107\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1104\",\"type\":\"GroupFilter\"},{\"id\":\"1105\",\"type\":\"GroupFilter\"},{\"id\":\"1106\",\"type\":\"GroupFilter\"},{\"id\":\"1107\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"}},\"id\":\"1108\",\"type\":\"CDSView\"},{\"attributes\":{\"color_mapper\":{\"id\":\"1040\",\"type\":\"LinearColorMapper\"},\"dh\":{\"units\":\"data\",\"value\":3.4511366685537075},\"dw\":{\"units\":\"data\",\"value\":3.3930259095244972},\"image\":{\"field\":\"image\"},\"x\":{\"value\":-1.7825845552138326},\"y\":{\"value\":-1.594487369895019}},\"id\":\"1042\",\"type\":\"Image\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"1109\",\"type\":\"GroupFilter\"},{\"attributes\":{\"color_mapper\":{\"id\":\"1040\",\"type\":\"LinearColorMapper\"},\"dh\":{\"units\":\"data\",\"value\":3.4511366685537075},\"dw\":{\"units\":\"data\",\"value\":3.3930259095244972},\"image\":{\"field\":\"image\"},\"x\":{\"value\":-1.7825845552138326},\"y\":{\"value\":-1.594487369895019}},\"id\":\"1043\",\"type\":\"Image\"},{\"attributes\":{\"data_source\":{\"id\":\"1041\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1042\",\"type\":\"Image\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1043\",\"type\":\"Image\"},\"selection_glyph\":null,\"view\":{\"id\":\"1045\",\"type\":\"CDSView\"}},\"id\":\"1044\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"1110\",\"type\":\"GroupFilter\"},{\"attributes\":{\"source\":{\"id\":\"1041\",\"type\":\"ColumnDataSource\"}},\"id\":\"1045\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1111\",\"type\":\"GroupFilter\"},{\"attributes\":{\"callback\":null,\"data\":{\"image\":[{\"__ndarray__\":\"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\",\"dtype\":\"float64\",\"shape\":[18,17]},{\"__ndarray__\":\"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\",\"dtype\":\"float64\",\"shape\":[18,17]},{\"__ndarray__\":\"fKha+OfHJ8B8qFr458cnwHyoWvjnxyfAfKha+OfHJ8B8qFr458cnwHyoWvjnxyfAfKha+OfHJ8AsQO41F0onwI75kwuosjfAzSvEECYKPcCarjqFb+JLwC6IWxj8Z1PALohbGPxnU8AuiFsY/GdTwC6IWxj8Z1PALohbGPxnU8AuiFsY/GdTwHyoWvjnxyfAfKha+OfHJ8B8qFr458cnwHyoWvjnxyfAfKha+OfHJ8B8qFr458cnwHyoWvjnxyfALEDuNRdKJ8CO+ZMLqLI3wM0rxBAmCj3Amq46hW/iS8AuiFsY/GdTwC6IWxj8Z1PALohbGPxnU8AuiFsY/GdTwC6IWxj8Z1PALohbGPxnU8B8qFr458cnwHyoWvjnxyfAfKha+OfHJ8B8qFr458cnwHyoWvjnxyfAfKha+OfHJ8B8qFr458cnwCxA7jUXSifAjvmTC6iyN8DNK8QQJgo9wJquOoVv4kvALohbGPxnU8AuiFsY/GdTwC6IWxj8Z1PALohbGPxnU8AuiFsY/GdTwC6IWxj8Z1PAfKha+OfHJ8B8qFr458cnwHyoWvjnxyfAfKha+OfHJ8B8qFr458cnwHyoWvjnxyfAfKha+OfHJ8AsQO41F0onwI75kwuosjfAzSvEECYKPcCarjqFb+JLwC6IWxj8Z1PALohbGPxnU8AuiFsY/GdTwC6IWxj8Z1PALohbGPxnU8AuiFsY/GdTwHyoWvjnxyfAfKha+OfHJ8B8qFr458cnwHyoWvjnxyfAfKha+OfHJ8B8qFr458cnwHyoWvjnxyfALEDuNRdKJ8CO+ZMLqLI3wM0rxBAmCj3Amq46hW/iS8AuiFsY/GdTwC6IWxj8Z1PALohbGPxnU8AuiFsY/GdTwC6IWxj8Z1PALohbGPxnU8B8qFr458cnwHyoWvjnxyfAfKha+OfHJ8B8qFr458cnwHyoWvjnxyfAfKha+OfHJ8B8qFr458cnwCxA7jUXSifAjvmTC6iyN8DNK8QQJgo9wJquOoVv4kvALohbGPxnU8AuiFsY/GdTwC6IWxj8Z1PALohbGPxnU8AuiFsY/GdTwC6IWxj8Z1PAfKha+OfHJ8B8qFr458cnwHyoWvjnxyfAfKha+OfHJ8B8qFr458cnwHyoWvjnxyfAfKha+OfHJ8AsQO41F0onwI75kwuosjfAzSvEECYKPcCarjqF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\",\"dtype\":\"float64\",\"shape\":[18,17]}]},\"selected\":{\"id\":\"1173\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1172\",\"type\":\"UnionRenderers\"}},\"id\":\"1046\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"booleans\":[true,true]},\"id\":\"1112\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"color_mapper\":{\"id\":\"1040\",\"type\":\"LinearColorMapper\"},\"dh\":{\"units\":\"data\",\"value\":3.4511366685537075},\"dw\":{\"units\":\"data\",\"value\":3.3930259095244972},\"image\":{\"field\":\"image\"},\"x\":{\"value\":-1.7825845552138326},\"y\":{\"value\":-1.594487369895019}},\"id\":\"1047\",\"type\":\"Image\"},{\"attributes\":{\"filters\":[{\"id\":\"1109\",\"type\":\"GroupFilter\"},{\"id\":\"1110\",\"type\":\"GroupFilter\"},{\"id\":\"1111\",\"type\":\"GroupFilter\"},{\"id\":\"1112\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"}},\"id\":\"1113\",\"type\":\"CDSView\"},{\"attributes\":{\"color_mapper\":{\"id\":\"1040\",\"type\":\"LinearColorMapper\"},\"dh\":{\"units\":\"data\",\"value\":3.4511366685537075},\"dw\":{\"units\":\"data\",\"value\":3.3930259095244972},\"image\":{\"field\":\"image\"},\"x\":{\"value\":-1.7825845552138326},\"y\":{\"value\":-1.594487369895019}},\"id\":\"1048\",\"type\":\"Image\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1115\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1046\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1047\",\"type\":\"Image\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1048\",\"type\":\"Image\"},\"selection_glyph\":null,\"view\":{\"id\":\"1050\",\"type\":\"CDSView\"},\"visible\":false},\"id\":\"1049\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"source\":{\"id\":\"1046\",\"type\":\"ColumnDataSource\"}},\"id\":\"1050\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1116\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"3227\",\"type\":\"GroupFilter\"},{\"id\":\"3228\",\"type\":\"GroupFilter\"},{\"id\":\"3229\",\"type\":\"GroupFilter\"},{\"id\":\"3230\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"}},\"id\":\"3231\",\"type\":\"CDSView\"},{\"attributes\":{\"args\":{\"colormapper\":{\"id\":\"1040\",\"type\":\"LinearColorMapper\"},\"glyph0\":{\"id\":\"1044\",\"type\":\"GlyphRenderer\"},\"glyph1\":{\"id\":\"1049\",\"type\":\"GlyphRenderer\"}},\"code\":\"var len_labels = 2,glyphs = [ glyph0,glyph1],mins = [-72.27169666666666, -77.62476166666667],maxs = [-11.867716666666666, -11.644708333333334];\\n for (i = 0; i < len_labels; i++) {\\n if (cb_obj.active === i) {\\n // console.log('Setting to true: ' + i);\\n glyphs[i].visible = true;\\n colormapper.low = mins[i];\\n colormapper.high = maxs[i];\\n } else {\\n // console.log('Setting to false: ' + i);\\n glyphs[i].visible = false;\\n }\\n }\\n \"},\"id\":\"4562\",\"type\":\"CustomJS\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true]},\"id\":\"3270\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"20\"},\"id\":\"4072\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1305\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"3267\",\"type\":\"GroupFilter\"},{\"id\":\"3268\",\"type\":\"GroupFilter\"},{\"id\":\"3269\",\"type\":\"GroupFilter\"},{\"id\":\"3270\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"}},\"id\":\"3271\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3224\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true]},\"id\":\"1306\",\"type\":\"BooleanFilter\"},{\"attributes\":{},\"id\":\"3742\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"active\":0,\"callback\":{\"id\":\"4562\",\"type\":\"CustomJS\"},\"labels\":[\"combined\",\"dqn seq del\"]},\"id\":\"4563\",\"type\":\"RadioButtonGroup\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true]},\"id\":\"3225\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"3272\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"3217\",\"type\":\"GroupFilter\"},{\"id\":\"3218\",\"type\":\"GroupFilter\"},{\"id\":\"3219\",\"type\":\"GroupFilter\"},{\"id\":\"3220\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"}},\"id\":\"3221\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"3743\",\"type\":\"Selection\"},{\"attributes\":{\"text\":\"Data used to estimate contour-plot\"},\"id\":\"4564\",\"type\":\"Div\"},{\"attributes\":{\"filters\":[{\"id\":\"1303\",\"type\":\"GroupFilter\"},{\"id\":\"1304\",\"type\":\"GroupFilter\"},{\"id\":\"1305\",\"type\":\"GroupFilter\"},{\"id\":\"1306\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"}},\"id\":\"1307\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"3273\",\"type\":\"GroupFilter\"},{\"attributes\":{\"children\":[{\"id\":\"4554\",\"type\":\"Slider\"}]},\"id\":\"4565\",\"type\":\"WidgetBox\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"4071\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"1308\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3229\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3274\",\"type\":\"GroupFilter\"},{\"attributes\":{\"children\":[{\"id\":\"1011\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"id\":\"4565\",\"type\":\"WidgetBox\"}]},\"id\":\"4566\",\"type\":\"Column\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"3233\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true]},\"id\":\"3275\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"children\":[{\"id\":\"4557\",\"type\":\"Div\"}]},\"id\":\"4567\",\"type\":\"WidgetBox\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"1309\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"3222\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"3272\",\"type\":\"GroupFilter\"},{\"id\":\"3273\",\"type\":\"GroupFilter\"},{\"id\":\"3274\",\"type\":\"GroupFilter\"},{\"id\":\"3275\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"}},\"id\":\"3276\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"4075\",\"type\":\"GroupFilter\"},{\"attributes\":{\"children\":[{\"id\":\"4555\",\"type\":\"CheckboxButtonGroup\"}]},\"id\":\"4568\",\"type\":\"WidgetBox\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1310\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4073\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"children\":[{\"id\":\"4559\",\"type\":\"Button\"}],\"width\":100},\"id\":\"4569\",\"type\":\"WidgetBox\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3278\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"3222\",\"type\":\"GroupFilter\"},{\"id\":\"3223\",\"type\":\"GroupFilter\"},{\"id\":\"3224\",\"type\":\"GroupFilter\"},{\"id\":\"3225\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"}},\"id\":\"3226\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true]},\"id\":\"1311\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"3223\",\"type\":\"GroupFilter\"},{\"attributes\":{\"children\":[{\"id\":\"4561\",\"type\":\"Button\"}],\"width\":100},\"id\":\"4570\",\"type\":\"WidgetBox\"},{\"attributes\":{\"filters\":[{\"id\":\"1308\",\"type\":\"GroupFilter\"},{\"id\":\"1309\",\"type\":\"GroupFilter\"},{\"id\":\"1310\",\"type\":\"GroupFilter\"},{\"id\":\"1311\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"}},\"id\":\"1312\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"4051\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3279\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"4077\",\"type\":\"GroupFilter\"},{\"attributes\":{\"children\":[{\"id\":\"4569\",\"type\":\"WidgetBox\"},{\"id\":\"4570\",\"type\":\"WidgetBox\"}]},\"id\":\"4571\",\"type\":\"Row\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"1313\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"4076\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3278\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3279\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3221\",\"type\":\"CDSView\"}},\"id\":\"3280\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true]},\"id\":\"3220\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"4056\",\"type\":\"GroupFilter\"},{\"attributes\":{\"children\":[{\"id\":\"4564\",\"type\":\"Div\"}]},\"id\":\"4572\",\"type\":\"WidgetBox\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"3228\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"1314\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"4080\",\"type\":\"GroupFilter\"},{\"attributes\":{\"children\":[{\"id\":\"4563\",\"type\":\"RadioButtonGroup\"}]},\"id\":\"4573\",\"type\":\"WidgetBox\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3311\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true]},\"id\":\"3230\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3282\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1315\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"4070\",\"type\":\"GroupFilter\"},{\"attributes\":{\"children\":[{\"id\":\"4567\",\"type\":\"WidgetBox\"},{\"id\":\"4568\",\"type\":\"WidgetBox\"},{\"id\":\"4571\",\"type\":\"Row\"},{\"id\":\"4572\",\"type\":\"WidgetBox\"},{\"id\":\"4573\",\"type\":\"WidgetBox\"}]},\"id\":\"4574\",\"type\":\"Column\"},{\"attributes\":{\"filters\":[{\"id\":\"4065\",\"type\":\"GroupFilter\"},{\"id\":\"4066\",\"type\":\"GroupFilter\"},{\"id\":\"4067\",\"type\":\"GroupFilter\"},{\"id\":\"4068\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4069\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3234\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3283\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"3232\",\"type\":\"GroupFilter\"},{\"id\":\"3233\",\"type\":\"GroupFilter\"},{\"id\":\"3234\",\"type\":\"GroupFilter\"},{\"id\":\"3235\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"}},\"id\":\"3236\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true]},\"id\":\"1316\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3282\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3283\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3226\",\"type\":\"CDSView\"}},\"id\":\"3284\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"1313\",\"type\":\"GroupFilter\"},{\"id\":\"1314\",\"type\":\"GroupFilter\"},{\"id\":\"1315\",\"type\":\"GroupFilter\"},{\"id\":\"1316\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"}},\"id\":\"1317\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true]},\"id\":\"3235\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"4070\",\"type\":\"GroupFilter\"},{\"id\":\"4071\",\"type\":\"GroupFilter\"},{\"id\":\"4072\",\"type\":\"GroupFilter\"},{\"id\":\"4073\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4074\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"1318\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"3238\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3310\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3286\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3239\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"1319\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3287\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"3237\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1320\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4078\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3286\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3287\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3231\",\"type\":\"CDSView\"}},\"id\":\"3288\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true]},\"id\":\"3240\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"4050\",\"type\":\"GroupFilter\"},{\"id\":\"4051\",\"type\":\"GroupFilter\"},{\"id\":\"4052\",\"type\":\"GroupFilter\"},{\"id\":\"4053\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4054\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true]},\"id\":\"1321\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"4055\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1318\",\"type\":\"GroupFilter\"},{\"id\":\"1319\",\"type\":\"GroupFilter\"},{\"id\":\"1320\",\"type\":\"GroupFilter\"},{\"id\":\"1321\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"}},\"id\":\"1322\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3290\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"3237\",\"type\":\"GroupFilter\"},{\"id\":\"3238\",\"type\":\"GroupFilter\"},{\"id\":\"3239\",\"type\":\"GroupFilter\"},{\"id\":\"3240\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"}},\"id\":\"3241\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4053\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"1323\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"3242\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"4057\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3291\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"20\"},\"id\":\"4052\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"4075\",\"type\":\"GroupFilter\"},{\"id\":\"4076\",\"type\":\"GroupFilter\"},{\"id\":\"4077\",\"type\":\"GroupFilter\"},{\"id\":\"4078\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4079\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3244\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3290\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3291\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3236\",\"type\":\"CDSView\"}},\"id\":\"3292\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"1324\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true]},\"id\":\"3245\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1325\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3306\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3307\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3256\",\"type\":\"CDSView\"}},\"id\":\"3308\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4058\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3294\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true]},\"id\":\"1326\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"3243\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"4055\",\"type\":\"GroupFilter\"},{\"id\":\"4056\",\"type\":\"GroupFilter\"},{\"id\":\"4057\",\"type\":\"GroupFilter\"},{\"id\":\"4058\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4059\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true]},\"id\":\"1346\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1323\",\"type\":\"GroupFilter\"},{\"id\":\"1324\",\"type\":\"GroupFilter\"},{\"id\":\"1325\",\"type\":\"GroupFilter\"},{\"id\":\"1326\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"}},\"id\":\"1327\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3295\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"3232\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"4060\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3294\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3295\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3241\",\"type\":\"CDSView\"}},\"id\":\"3296\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"1328\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"3227\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"4061\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3307\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"1329\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3298\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"20\"},\"id\":\"4062\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1330\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3299\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"3242\",\"type\":\"GroupFilter\"},{\"id\":\"3243\",\"type\":\"GroupFilter\"},{\"id\":\"3244\",\"type\":\"GroupFilter\"},{\"id\":\"3245\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"}},\"id\":\"3246\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4063\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"booleans\":[true,true,true]},\"id\":\"1331\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"3247\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3298\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3299\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3246\",\"type\":\"CDSView\"}},\"id\":\"3300\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"4060\",\"type\":\"GroupFilter\"},{\"id\":\"4061\",\"type\":\"GroupFilter\"},{\"id\":\"4062\",\"type\":\"GroupFilter\"},{\"id\":\"4063\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4064\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"3248\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1328\",\"type\":\"GroupFilter\"},{\"id\":\"1329\",\"type\":\"GroupFilter\"},{\"id\":\"1330\",\"type\":\"GroupFilter\"},{\"id\":\"1331\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"}},\"id\":\"1332\",\"type\":\"CDSView\"},{\"attributes\":{\"filters\":[{\"id\":\"3247\",\"type\":\"GroupFilter\"},{\"id\":\"3248\",\"type\":\"GroupFilter\"},{\"id\":\"3249\",\"type\":\"GroupFilter\"},{\"id\":\"3250\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"}},\"id\":\"3251\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"3606\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"4065\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3306\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"1333\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3249\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3302\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"4066\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3303\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"1334\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true]},\"id\":\"3250\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"4067\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3302\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3303\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3251\",\"type\":\"CDSView\"}},\"id\":\"3304\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1335\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4068\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1959\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"1887\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1368\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1369\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1312\",\"type\":\"CDSView\"}},\"id\":\"1370\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"2186\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1958\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1959\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1910\",\"type\":\"CDSView\"}},\"id\":\"1960\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1888\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"1917\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"2185\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1589\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1918\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true]},\"id\":\"2188\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1372\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1893\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1962\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"2180\",\"type\":\"GroupFilter\"},{\"id\":\"2181\",\"type\":\"GroupFilter\"},{\"id\":\"2182\",\"type\":\"GroupFilter\"},{\"id\":\"2183\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"}},\"id\":\"2184\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true,true,true]},\"id\":\"1919\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1373\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"1892\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2187\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1963\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"1916\",\"type\":\"GroupFilter\"},{\"id\":\"1917\",\"type\":\"GroupFilter\"},{\"id\":\"1918\",\"type\":\"GroupFilter\"},{\"id\":\"1919\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"}},\"id\":\"1920\",\"type\":\"CDSView\"},{\"attributes\":{\"data_source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1372\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1373\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1317\",\"type\":\"CDSView\"}},\"id\":\"1374\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true]},\"id\":\"2193\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1962\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1963\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1915\",\"type\":\"CDSView\"}},\"id\":\"1964\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1922\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"2853\",\"type\":\"GroupFilter\"},{\"id\":\"2854\",\"type\":\"GroupFilter\"},{\"id\":\"2855\",\"type\":\"GroupFilter\"},{\"id\":\"2856\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"}},\"id\":\"2857\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"1592\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"1891\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true]},\"id\":\"2183\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2192\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1376\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"1886\",\"type\":\"GroupFilter\"},{\"id\":\"1887\",\"type\":\"GroupFilter\"},{\"id\":\"1888\",\"type\":\"GroupFilter\"},{\"id\":\"1889\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"}},\"id\":\"1890\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"2191\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1966\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1923\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"2869\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1377\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true]},\"id\":\"1889\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"2190\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1922\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1923\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1865\",\"type\":\"CDSView\"}},\"id\":\"1924\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1967\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"2629\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"data_source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1376\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1377\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1322\",\"type\":\"CDSView\"}},\"id\":\"1378\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"2185\",\"type\":\"GroupFilter\"},{\"id\":\"2186\",\"type\":\"GroupFilter\"},{\"id\":\"2187\",\"type\":\"GroupFilter\"},{\"id\":\"2188\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"}},\"id\":\"2189\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true,true,true]},\"id\":\"1894\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1966\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1967\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1920\",\"type\":\"CDSView\"}},\"id\":\"1968\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"2630\",\"type\":\"Selection\"},{\"attributes\":{\"filters\":[{\"id\":\"1891\",\"type\":\"GroupFilter\"},{\"id\":\"1892\",\"type\":\"GroupFilter\"},{\"id\":\"1893\",\"type\":\"GroupFilter\"},{\"id\":\"1894\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"}},\"id\":\"1895\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1955\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1926\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"1896\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"2210\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"2853\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1380\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2870\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1927\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1381\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1666\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1926\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1927\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1870\",\"type\":\"CDSView\"}},\"id\":\"1928\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"1897\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"2874\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1380\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1381\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1327\",\"type\":\"CDSView\"}},\"id\":\"1382\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"2190\",\"type\":\"GroupFilter\"},{\"id\":\"2191\",\"type\":\"GroupFilter\"},{\"id\":\"2192\",\"type\":\"GroupFilter\"},{\"id\":\"2193\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"}},\"id\":\"2194\",\"type\":\"CDSView\"},{\"attributes\":{\"filters\":[{\"id\":\"1896\",\"type\":\"GroupFilter\"},{\"id\":\"1897\",\"type\":\"GroupFilter\"},{\"id\":\"1898\",\"type\":\"GroupFilter\"},{\"id\":\"1899\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"}},\"id\":\"1900\",\"type\":\"CDSView\"},{\"attributes\":{\"data_source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1661\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1662\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1611\",\"type\":\"CDSView\"}},\"id\":\"1663\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1954\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"2878\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1930\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"2210\",\"type\":\"GroupFilter\"},{\"id\":\"2211\",\"type\":\"GroupFilter\"},{\"id\":\"2212\",\"type\":\"GroupFilter\"},{\"id\":\"2213\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"}},\"id\":\"2214\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"1901\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1384\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true]},\"id\":\"1899\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"2868\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1931\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"2215\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1385\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1898\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1930\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1931\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1875\",\"type\":\"CDSView\"}},\"id\":\"1932\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1384\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1385\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1332\",\"type\":\"CDSView\"}},\"id\":\"1386\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"2868\",\"type\":\"GroupFilter\"},{\"id\":\"2869\",\"type\":\"GroupFilter\"},{\"id\":\"2870\",\"type\":\"GroupFilter\"},{\"id\":\"2871\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"}},\"id\":\"2872\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1669\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"2873\",\"type\":\"GroupFilter\"},{\"id\":\"2874\",\"type\":\"GroupFilter\"},{\"id\":\"2875\",\"type\":\"GroupFilter\"},{\"id\":\"2876\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"}},\"id\":\"2877\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"1902\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1587\",\"type\":\"GroupFilter\"},{\"id\":\"1588\",\"type\":\"GroupFilter\"},{\"id\":\"1589\",\"type\":\"GroupFilter\"},{\"id\":\"1590\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"}},\"id\":\"1591\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1934\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"2171\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2197\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1388\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1903\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true]},\"id\":\"2198\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1935\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"2196\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"2201\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"2859\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1389\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"1906\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1934\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1935\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1880\",\"type\":\"CDSView\"}},\"id\":\"1936\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1388\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1389\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1337\",\"type\":\"CDSView\"}},\"id\":\"1390\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2875\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1665\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1666\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1616\",\"type\":\"CDSView\"}},\"id\":\"1667\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"1901\",\"type\":\"GroupFilter\"},{\"id\":\"1902\",\"type\":\"GroupFilter\"},{\"id\":\"1903\",\"type\":\"GroupFilter\"},{\"id\":\"1904\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"}},\"id\":\"1905\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"2195\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"2858\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1950\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1951\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1900\",\"type\":\"CDSView\"}},\"id\":\"1952\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"1588\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1662\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1938\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"2195\",\"type\":\"GroupFilter\"},{\"id\":\"2196\",\"type\":\"GroupFilter\"},{\"id\":\"2197\",\"type\":\"GroupFilter\"},{\"id\":\"2198\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"}},\"id\":\"2199\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true,true,true]},\"id\":\"1904\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1392\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1908\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"2175\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1939\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2177\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"2200\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true]},\"id\":\"2871\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1393\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2264\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"1861\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1938\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1939\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1885\",\"type\":\"CDSView\"}},\"id\":\"1940\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"1907\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true]},\"id\":\"1909\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"2176\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1392\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1393\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1342\",\"type\":\"CDSView\"}},\"id\":\"1394\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1987\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true]},\"id\":\"2203\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"2863\",\"type\":\"GroupFilter\"},{\"id\":\"2864\",\"type\":\"GroupFilter\"},{\"id\":\"2865\",\"type\":\"GroupFilter\"},{\"id\":\"2866\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"}},\"id\":\"2867\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"2864\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1951\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true]},\"id\":\"1590\",\"type\":\"BooleanFilter\"},{\"attributes\":{},\"id\":\"1988\",\"type\":\"Selection\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1942\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"1593\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"1912\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2202\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1396\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true]},\"id\":\"2213\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true]},\"id\":\"2876\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1943\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"1911\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1397\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"2200\",\"type\":\"GroupFilter\"},{\"id\":\"2201\",\"type\":\"GroupFilter\"},{\"id\":\"2202\",\"type\":\"GroupFilter\"},{\"id\":\"2203\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"}},\"id\":\"2204\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2855\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1942\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1943\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1890\",\"type\":\"CDSView\"}},\"id\":\"1944\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"1906\",\"type\":\"GroupFilter\"},{\"id\":\"1907\",\"type\":\"GroupFilter\"},{\"id\":\"1908\",\"type\":\"GroupFilter\"},{\"id\":\"1909\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"}},\"id\":\"1910\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true]},\"id\":\"2173\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2860\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1396\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1397\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1347\",\"type\":\"CDSView\"}},\"id\":\"1398\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"1866\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"2205\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"2180\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1950\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"1426\",\"type\":\"Selection\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"1862\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1665\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1946\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"1886\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"2206\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1400\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2865\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1670\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"1881\",\"type\":\"GroupFilter\"},{\"id\":\"1882\",\"type\":\"GroupFilter\"},{\"id\":\"1883\",\"type\":\"GroupFilter\"},{\"id\":\"1884\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"}},\"id\":\"1885\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1947\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"2181\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1401\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2207\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true]},\"id\":\"2866\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1946\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1947\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1895\",\"type\":\"CDSView\"}},\"id\":\"1948\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"2170\",\"type\":\"GroupFilter\"},{\"id\":\"2171\",\"type\":\"GroupFilter\"},{\"id\":\"2172\",\"type\":\"GroupFilter\"},{\"id\":\"2173\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"}},\"id\":\"2174\",\"type\":\"CDSView\"},{\"attributes\":{\"filters\":[{\"id\":\"2858\",\"type\":\"GroupFilter\"},{\"id\":\"2859\",\"type\":\"GroupFilter\"},{\"id\":\"2860\",\"type\":\"GroupFilter\"},{\"id\":\"2861\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"}},\"id\":\"2862\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true]},\"id\":\"2208\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1400\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1401\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1352\",\"type\":\"CDSView\"}},\"id\":\"1402\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"2175\",\"type\":\"GroupFilter\"},{\"id\":\"2176\",\"type\":\"GroupFilter\"},{\"id\":\"2177\",\"type\":\"GroupFilter\"},{\"id\":\"2178\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"}},\"id\":\"2179\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"2854\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1954\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1955\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1905\",\"type\":\"CDSView\"}},\"id\":\"1956\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"2205\",\"type\":\"GroupFilter\"},{\"id\":\"2206\",\"type\":\"GroupFilter\"},{\"id\":\"2207\",\"type\":\"GroupFilter\"},{\"id\":\"2208\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"}},\"id\":\"2209\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1913\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1911\",\"type\":\"GroupFilter\"},{\"id\":\"1912\",\"type\":\"GroupFilter\"},{\"id\":\"1913\",\"type\":\"GroupFilter\"},{\"id\":\"1914\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"}},\"id\":\"1915\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1425\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2172\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"1916\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"2170\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true]},\"id\":\"2178\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"2211\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1404\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true]},\"id\":\"1914\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2182\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1958\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2212\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true]},\"id\":\"2861\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1405\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true]},\"id\":\"2856\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2954\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2953\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2954\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2907\",\"type\":\"CDSView\"}},\"id\":\"2955\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1878\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true]},\"id\":\"1356\",\"type\":\"BooleanFilter\"},{\"attributes\":{},\"id\":\"1697\",\"type\":\"Selection\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"3253\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true]},\"id\":\"3260\",\"type\":\"BooleanFilter\"},{\"attributes\":{},\"id\":\"2980\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"1358\",\"type\":\"GroupFilter\"},{\"attributes\":{},\"id\":\"2981\",\"type\":\"Selection\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3259\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"3263\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true]},\"id\":\"3265\",\"type\":\"BooleanFilter\"},{\"attributes\":{},\"id\":\"4261\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"4262\",\"type\":\"Selection\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3254\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"3262\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"3258\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"3252\",\"type\":\"GroupFilter\"},{\"id\":\"3253\",\"type\":\"GroupFilter\"},{\"id\":\"3254\",\"type\":\"GroupFilter\"},{\"id\":\"3255\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"}},\"id\":\"3256\",\"type\":\"CDSView\"},{\"attributes\":{\"filters\":[{\"id\":\"3257\",\"type\":\"GroupFilter\"},{\"id\":\"3258\",\"type\":\"GroupFilter\"},{\"id\":\"3259\",\"type\":\"GroupFilter\"},{\"id\":\"3260\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"}},\"id\":\"3261\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"3268\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1868\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"3262\",\"type\":\"GroupFilter\"},{\"id\":\"3263\",\"type\":\"GroupFilter\"},{\"id\":\"3264\",\"type\":\"GroupFilter\"},{\"id\":\"3265\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"}},\"id\":\"3266\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"3267\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3264\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"1876\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3269\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true]},\"id\":\"3255\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1669\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1670\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1621\",\"type\":\"CDSView\"}},\"id\":\"1671\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"3257\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"3611\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true]},\"id\":\"1361\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2593\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4148\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true]},\"id\":\"1336\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1155\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1156\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1108\",\"type\":\"CDSView\"}},\"id\":\"1157\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2909\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2910\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2852\",\"type\":\"CDSView\"}},\"id\":\"2911\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"axis_label\":\"MDS-Y\",\"axis_label_text_font_size\":{\"value\":\"15pt\"},\"formatter\":{\"id\":\"1167\",\"type\":\"BasicTickFormatter\"},\"major_label_text_font_size\":{\"value\":\"12pt\"},\"ticker\":{\"id\":\"1026\",\"type\":\"BasicTicker\"}},\"id\":\"1025\",\"type\":\"LinearAxis\"},{\"attributes\":{\"desired_num_ticks\":15},\"id\":\"1051\",\"type\":\"BasicTicker\"},{\"attributes\":{\"filters\":[{\"id\":\"1333\",\"type\":\"GroupFilter\"},{\"id\":\"1334\",\"type\":\"GroupFilter\"},{\"id\":\"1335\",\"type\":\"GroupFilter\"},{\"id\":\"1336\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"}},\"id\":\"1337\",\"type\":\"CDSView\"},{\"attributes\":{\"filters\":[{\"id\":\"1622\",\"type\":\"GroupFilter\"},{\"id\":\"1623\",\"type\":\"GroupFilter\"},{\"id\":\"1624\",\"type\":\"GroupFilter\"},{\"id\":\"1625\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"}},\"id\":\"1626\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2572\",\"type\":\"Scatter\"},{\"attributes\":{\"color_mapper\":{\"id\":\"1040\",\"type\":\"LinearColorMapper\"},\"formatter\":{\"id\":\"1164\",\"type\":\"BasicTickFormatter\"},\"label_standoff\":12,\"location\":[0,0],\"major_label_text_font_size\":{\"value\":\"12pt\"},\"ticker\":{\"id\":\"1051\",\"type\":\"BasicTicker\"}},\"id\":\"1052\",\"type\":\"ColorBar\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2942\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4149\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4148\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4149\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4034\",\"type\":\"CDSView\"}},\"id\":\"4150\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2573\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"1026\",\"type\":\"BasicTicker\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"1338\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1159\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2913\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"1627\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2572\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2573\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2518\",\"type\":\"CDSView\"}},\"id\":\"2574\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4200\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"1628\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3608\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1160\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2914\",\"type\":\"Scatter\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"red\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\"],\"origin\":[\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\"],\"p_delay\":[\"None\",\"None\",\"None\",\"None\",1,1,1,1,2,2,2,2,4,4],\"p_sequence_length\":[1,2,3,4,1,2,3,4,1,2,3,4,1,2],\"runs\":[1,1,1,1,1,1,1,1,1,1,1,1,1,1],\"size\":[12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0],\"type\":[\"Final Incumbent\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\"],\"x\":{\"__ndarray__\":\"9XycTryI4z8V1Y/pH4nVP33uZXS0Jq8/nYRVUx7zyL/jng7jxhThP6T+EOPF7tA/ZyIjRMDzOT9NoCikMQ/Pv52J5DpVYt4/vIle97OdyT9U/iO4yVyyv9fmb0ChoNS/bHPta/FD1z83ME5yQuCzPw==\",\"dtype\":\"float64\",\"shape\":[14]},\"y\":{\"__ndarray__\":\"mzBNdScfwr/cguHH3HPRv8eNZF3Badu/c7FyYAoG47/ygmwPQ8SivzX5O1I4IcS/mkKm6HCl078HiqO8Tmrev+mQWWh3ybc/XU2yO8n9oL+KgUkYMf7Hv/TTqU536ta/ePHIKFAr1z/sli0p0TnMPw==\",\"dtype\":\"float64\",\"shape\":[14]},\"zorder\":[\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\"]},\"selected\":{\"id\":\"3743\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"3742\",\"type\":\"UnionRenderers\"}},\"id\":\"1009\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2592\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4152\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"1054\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"1339\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1159\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1160\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1113\",\"type\":\"CDSView\"}},\"id\":\"1161\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2913\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2914\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2857\",\"type\":\"CDSView\"}},\"id\":\"2915\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1340\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2576\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4153\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"1055\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true]},\"id\":\"1630\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2941\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true]},\"id\":\"1341\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3638\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4152\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4153\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4039\",\"type\":\"CDSView\"}},\"id\":\"4154\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"1627\",\"type\":\"GroupFilter\"},{\"id\":\"1628\",\"type\":\"GroupFilter\"},{\"id\":\"1629\",\"type\":\"GroupFilter\"},{\"id\":\"1630\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"}},\"id\":\"1631\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2577\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1056\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1338\",\"type\":\"GroupFilter\"},{\"id\":\"1339\",\"type\":\"GroupFilter\"},{\"id\":\"1340\",\"type\":\"GroupFilter\"},{\"id\":\"1341\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"}},\"id\":\"1342\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2917\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"3612\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1677\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1678\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1631\",\"type\":\"CDSView\"}},\"id\":\"1679\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2576\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2577\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2523\",\"type\":\"CDSView\"}},\"id\":\"2578\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"dimension\":1,\"ticker\":{\"id\":\"1026\",\"type\":\"BasicTicker\"}},\"id\":\"1029\",\"type\":\"Grid\"},{\"attributes\":{\"callback\":null,\"end\":10,\"js_property_callbacks\":{\"change:value\":[{\"id\":\"4556\",\"type\":\"CustomJS\"}]},\"start\":1,\"title\":\"Until wallclocktime 21.90. Step no. \",\"value\":10},\"id\":\"4554\",\"type\":\"Slider\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1633\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2918\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true]},\"id\":\"1057\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1054\",\"type\":\"GroupFilter\"},{\"id\":\"1055\",\"type\":\"GroupFilter\"},{\"id\":\"1056\",\"type\":\"GroupFilter\"},{\"id\":\"1057\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"}},\"id\":\"1058\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4156\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"1343\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true]},\"id\":\"2851\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2917\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2918\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2862\",\"type\":\"CDSView\"}},\"id\":\"2919\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"3252\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3613\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1634\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2580\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4157\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"1059\",\"type\":\"GroupFilter\"},{\"attributes\":{\"ticker\":{\"id\":\"1021\",\"type\":\"BasicTicker\"}},\"id\":\"1024\",\"type\":\"Grid\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"1344\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3618\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1633\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1634\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1576\",\"type\":\"CDSView\"}},\"id\":\"1635\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4156\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4157\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4044\",\"type\":\"CDSView\"}},\"id\":\"4158\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2581\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1345\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2921\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"1021\",\"type\":\"BasicTicker\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"1060\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2580\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2581\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2528\",\"type\":\"CDSView\"}},\"id\":\"2582\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4196\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4197\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4094\",\"type\":\"CDSView\"}},\"id\":\"4198\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1678\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"3606\",\"type\":\"GroupFilter\"},{\"id\":\"3607\",\"type\":\"GroupFilter\"},{\"id\":\"3608\",\"type\":\"GroupFilter\"},{\"id\":\"3609\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"}},\"id\":\"3610\",\"type\":\"CDSView\"},{\"attributes\":{\"axis_label\":\"MDS-X\",\"axis_label_text_font_size\":{\"value\":\"15pt\"},\"formatter\":{\"id\":\"1165\",\"type\":\"BasicTickFormatter\"},\"major_label_text_font_size\":{\"value\":\"12pt\"},\"ticker\":{\"id\":\"1021\",\"type\":\"BasicTicker\"}},\"id\":\"1020\",\"type\":\"LinearAxis\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2922\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1061\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2588\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2589\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2538\",\"type\":\"CDSView\"}},\"id\":\"2590\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"1343\",\"type\":\"GroupFilter\"},{\"id\":\"1344\",\"type\":\"GroupFilter\"},{\"id\":\"1345\",\"type\":\"GroupFilter\"},{\"id\":\"1346\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"}},\"id\":\"1347\",\"type\":\"CDSView\"},{\"attributes\":{\"filters\":[{\"id\":\"1866\",\"type\":\"GroupFilter\"},{\"id\":\"1867\",\"type\":\"GroupFilter\"},{\"id\":\"1868\",\"type\":\"GroupFilter\"},{\"id\":\"1869\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"}},\"id\":\"1870\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1637\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2921\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2922\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2867\",\"type\":\"CDSView\"}},\"id\":\"2923\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4160\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true]},\"id\":\"1062\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2263\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2264\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2214\",\"type\":\"CDSView\"}},\"id\":\"2265\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1638\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2584\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4161\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2937\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2938\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2887\",\"type\":\"CDSView\"}},\"id\":\"2939\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"1059\",\"type\":\"GroupFilter\"},{\"id\":\"1060\",\"type\":\"GroupFilter\"},{\"id\":\"1061\",\"type\":\"GroupFilter\"},{\"id\":\"1062\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"}},\"id\":\"1063\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"1348\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1637\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1638\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1581\",\"type\":\"CDSView\"}},\"id\":\"1639\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4160\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4161\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4049\",\"type\":\"CDSView\"}},\"id\":\"4162\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2585\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"1696\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2925\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"1064\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"1349\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2584\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2585\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2533\",\"type\":\"CDSView\"}},\"id\":\"2586\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1018\",\"type\":\"LinearScale\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1677\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4197\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"1016\",\"type\":\"LinearScale\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2926\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"3616\",\"type\":\"GroupFilter\"},{\"id\":\"3617\",\"type\":\"GroupFilter\"},{\"id\":\"3618\",\"type\":\"GroupFilter\"},{\"id\":\"3619\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"}},\"id\":\"3620\",\"type\":\"CDSView\"},{\"attributes\":{\"data_source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2592\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2593\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2543\",\"type\":\"CDSView\"}},\"id\":\"2594\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1641\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4164\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"1065\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2925\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2926\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2872\",\"type\":\"CDSView\"}},\"id\":\"2927\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1350\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true]},\"id\":\"1351\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1642\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"3631\",\"type\":\"GroupFilter\"},{\"id\":\"3632\",\"type\":\"GroupFilter\"},{\"id\":\"3633\",\"type\":\"GroupFilter\"},{\"id\":\"3634\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"}},\"id\":\"3635\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4165\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1066\",\"type\":\"GroupFilter\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"red\",\"white\",\"white\"],\"origin\":[\"Random\",\"Random\",\"Random\"],\"p_delay\":[\"None\",\"None\",\"None\"],\"p_sequence_length\":[1,2,3],\"runs\":[1,1,1],\"size\":[12.0,12.0,12.0],\"type\":[\"Final Incumbent\",\"Candidate\",\"Candidate\"],\"x\":{\"__ndarray__\":\"9XycTryI4z8V1Y/pH4nVP33uZXS0Jq8/\",\"dtype\":\"float64\",\"shape\":[3]},\"y\":{\"__ndarray__\":\"mzBNdScfwr/cguHH3HPRv8eNZF3Badu/\",\"dtype\":\"float64\",\"shape\":[3]},\"zorder\":[\"0\",\"0\",\"0\"]},\"selected\":{\"id\":\"1426\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1425\",\"type\":\"UnionRenderers\"}},\"id\":\"1002\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"filters\":[{\"id\":\"1348\",\"type\":\"GroupFilter\"},{\"id\":\"1349\",\"type\":\"GroupFilter\"},{\"id\":\"1350\",\"type\":\"GroupFilter\"},{\"id\":\"1351\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"}},\"id\":\"1352\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2938\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1641\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1642\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1586\",\"type\":\"CDSView\"}},\"id\":\"1643\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4164\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4165\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4054\",\"type\":\"CDSView\"}},\"id\":\"4166\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2596\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true]},\"id\":\"1067\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2929\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"1353\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1873\",\"type\":\"GroupFilter\"},{\"attributes\":{\"callback\":null,\"end\":1.8566492986586884,\"start\":-1.594487369895019},\"id\":\"1014\",\"type\":\"Range1d\"},{\"attributes\":{\"filters\":[{\"id\":\"1064\",\"type\":\"GroupFilter\"},{\"id\":\"1065\",\"type\":\"GroupFilter\"},{\"id\":\"1066\",\"type\":\"GroupFilter\"},{\"id\":\"1067\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"}},\"id\":\"1068\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2597\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4196\",\"type\":\"Scatter\"},{\"attributes\":{\"callback\":null,\"end\":1.6104413543106646,\"start\":-1.7825845552138326},\"id\":\"1012\",\"type\":\"Range1d\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2930\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true]},\"id\":\"1864\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2596\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2597\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2548\",\"type\":\"CDSView\"}},\"id\":\"2598\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1164\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1645\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4168\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2929\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2930\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2877\",\"type\":\"CDSView\"}},\"id\":\"2931\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"1069\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"1354\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1646\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4169\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"1165\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1355\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2937\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"3611\",\"type\":\"GroupFilter\"},{\"id\":\"3612\",\"type\":\"GroupFilter\"},{\"id\":\"3613\",\"type\":\"GroupFilter\"},{\"id\":\"3614\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"}},\"id\":\"3615\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"1070\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1871\",\"type\":\"GroupFilter\"},{\"id\":\"1872\",\"type\":\"GroupFilter\"},{\"id\":\"1873\",\"type\":\"GroupFilter\"},{\"id\":\"1874\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"}},\"id\":\"1875\",\"type\":\"CDSView\"},{\"attributes\":{\"background_fill_color\":{\"value\":null},\"below\":[{\"id\":\"1020\",\"type\":\"LinearAxis\"}],\"border_fill_color\":{\"value\":null},\"center\":[{\"id\":\"1024\",\"type\":\"Grid\"},{\"id\":\"1029\",\"type\":\"Grid\"}],\"left\":[{\"id\":\"1025\",\"type\":\"LinearAxis\"}],\"plot_height\":500,\"renderers\":[{\"id\":\"1044\",\"type\":\"GlyphRenderer\"},{\"id\":\"1049\",\"type\":\"GlyphRenderer\"},{\"id\":\"1117\",\"type\":\"GlyphRenderer\"},{\"id\":\"1121\",\"type\":\"GlyphRenderer\"},{\"id\":\"1125\",\"type\":\"GlyphRenderer\"},{\"id\":\"1129\",\"type\":\"GlyphRenderer\"},{\"id\":\"1133\",\"type\":\"GlyphRenderer\"},{\"id\":\"1137\",\"type\":\"GlyphRenderer\"},{\"id\":\"1141\",\"type\":\"GlyphRenderer\"},{\"id\":\"1145\",\"type\":\"GlyphRenderer\"},{\"id\":\"1149\",\"type\":\"GlyphRenderer\"},{\"id\":\"1153\",\"type\":\"GlyphRenderer\"},{\"id\":\"1157\",\"type\":\"GlyphRenderer\"},{\"id\":\"1161\",\"type\":\"GlyphRenderer\"},{\"id\":\"1366\",\"type\":\"GlyphRenderer\"},{\"id\":\"1370\",\"type\":\"GlyphRenderer\"},{\"id\":\"1374\",\"type\":\"GlyphRenderer\"},{\"id\":\"1378\",\"type\":\"GlyphRenderer\"},{\"id\":\"1382\",\"type\":\"GlyphRenderer\"},{\"id\":\"1386\",\"type\":\"GlyphRenderer\"},{\"id\":\"1390\",\"type\":\"GlyphRenderer\"},{\"id\":\"1394\",\"type\":\"GlyphRenderer\"},{\"id\":\"1398\",\"type\":\"GlyphRenderer\"},{\"id\":\"1402\",\"type\":\"GlyphRenderer\"},{\"id\":\"1406\",\"type\":\"GlyphRenderer\"},{\"id\":\"1410\",\"type\":\"GlyphRenderer\"},{\"id\":\"1635\",\"type\":\"GlyphRenderer\"},{\"id\":\"1639\",\"type\":\"GlyphRenderer\"},{\"id\":\"1643\",\"type\":\"GlyphRenderer\"},{\"id\":\"1647\",\"type\":\"GlyphRenderer\"},{\"id\":\"1651\",\"type\":\"GlyphRenderer\"},{\"id\":\"1655\",\"type\":\"GlyphRenderer\"},{\"id\":\"1659\",\"type\":\"GlyphRenderer\"},{\"id\":\"1663\",\"type\":\"GlyphRenderer\"},{\"id\":\"1667\",\"type\":\"GlyphRenderer\"},{\"id\":\"1671\",\"type\":\"GlyphRenderer\"},{\"id\":\"1675\",\"type\":\"GlyphRenderer\"},{\"id\":\"1679\",\"type\":\"GlyphRenderer\"},{\"id\":\"1924\",\"type\":\"GlyphRenderer\"},{\"id\":\"1928\",\"type\":\"GlyphRenderer\"},{\"id\":\"1932\",\"type\":\"GlyphRenderer\"},{\"id\":\"1936\",\"type\":\"GlyphRenderer\"},{\"id\":\"1940\",\"type\":\"GlyphRenderer\"},{\"id\":\"1944\",\"type\":\"GlyphRenderer\"},{\"id\":\"1948\",\"type\":\"GlyphRenderer\"},{\"id\":\"1952\",\"type\":\"GlyphRenderer\"},{\"id\":\"1956\",\"type\":\"GlyphRenderer\"},{\"id\":\"1960\",\"type\":\"GlyphRenderer\"},{\"id\":\"1964\",\"type\":\"GlyphRenderer\"},{\"id\":\"1968\",\"type\":\"GlyphRenderer\"},{\"id\":\"2233\",\"type\":\"GlyphRenderer\"},{\"id\":\"2237\",\"type\":\"GlyphRenderer\"},{\"id\":\"2241\",\"type\":\"GlyphRenderer\"},{\"id\":\"2245\",\"type\":\"GlyphRenderer\"},{\"id\":\"2249\",\"type\":\"GlyphRenderer\"},{\"id\":\"2253\",\"type\":\"GlyphRenderer\"},{\"id\":\"2257\",\"type\":\"GlyphRenderer\"},{\"id\":\"2261\",\"type\":\"GlyphRenderer\"},{\"id\":\"2265\",\"type\":\"GlyphRenderer\"},{\"id\":\"2269\",\"type\":\"GlyphRenderer\"},{\"id\":\"2273\",\"type\":\"GlyphRenderer\"},{\"id\":\"2277\",\"type\":\"GlyphRenderer\"},{\"id\":\"2562\",\"type\":\"GlyphRenderer\"},{\"id\":\"2566\",\"type\":\"GlyphRenderer\"},{\"id\":\"2570\",\"type\":\"GlyphRenderer\"},{\"id\":\"2574\",\"type\":\"GlyphRenderer\"},{\"id\":\"2578\",\"type\":\"GlyphRenderer\"},{\"id\":\"2582\",\"type\":\"GlyphRenderer\"},{\"id\":\"2586\",\"type\":\"GlyphRenderer\"},{\"id\":\"2590\",\"type\":\"GlyphRenderer\"},{\"id\":\"2594\",\"type\":\"GlyphRenderer\"},{\"id\":\"2598\",\"type\":\"GlyphRenderer\"},{\"id\":\"2602\",\"type\":\"GlyphRenderer\"},{\"id\":\"2606\",\"type\":\"GlyphRenderer\"},{\"id\":\"2911\",\"type\":\"GlyphRenderer\"},{\"id\":\"2915\",\"type\":\"GlyphRenderer\"},{\"id\":\"2919\",\"type\":\"GlyphRenderer\"},{\"id\":\"2923\",\"type\":\"GlyphRenderer\"},{\"id\":\"2927\",\"type\":\"GlyphRenderer\"},{\"id\":\"2931\",\"type\":\"GlyphRenderer\"},{\"id\":\"2935\",\"type\":\"GlyphRenderer\"},{\"id\":\"2939\",\"type\":\"GlyphRenderer\"},{\"id\":\"2943\",\"type\":\"GlyphRenderer\"},{\"id\":\"2947\",\"type\":\"GlyphRenderer\"},{\"id\":\"2951\",\"type\":\"GlyphRenderer\"},{\"id\":\"2955\",\"type\":\"GlyphRenderer\"},{\"id\":\"3280\",\"type\":\"GlyphRenderer\"},{\"id\":\"3284\",\"type\":\"GlyphRenderer\"},{\"id\":\"3288\",\"type\":\"GlyphRenderer\"},{\"id\":\"3292\",\"type\":\"GlyphRenderer\"},{\"id\":\"3296\",\"type\":\"GlyphRenderer\"},{\"id\":\"3300\",\"type\":\"GlyphRenderer\"},{\"id\":\"3304\",\"type\":\"GlyphRenderer\"},{\"id\":\"3308\",\"type\":\"GlyphRenderer\"},{\"id\":\"3312\",\"type\":\"GlyphRenderer\"},{\"id\":\"3316\",\"type\":\"GlyphRenderer\"},{\"id\":\"3320\",\"type\":\"GlyphRenderer\"},{\"id\":\"3324\",\"type\":\"GlyphRenderer\"},{\"id\":\"3669\",\"type\":\"GlyphRenderer\"},{\"id\":\"3673\",\"type\":\"GlyphRenderer\"},{\"id\":\"3677\",\"type\":\"GlyphRenderer\"},{\"id\":\"3681\",\"type\":\"GlyphRenderer\"},{\"id\":\"3685\",\"type\":\"GlyphRenderer\"},{\"id\":\"3689\",\"type\":\"GlyphRenderer\"},{\"id\":\"3693\",\"type\":\"GlyphRenderer\"},{\"id\":\"3697\",\"type\":\"GlyphRenderer\"},{\"id\":\"3701\",\"type\":\"GlyphRenderer\"},{\"id\":\"3705\",\"type\":\"GlyphRenderer\"},{\"id\":\"3709\",\"type\":\"GlyphRenderer\"},{\"id\":\"3713\",\"type\":\"GlyphRenderer\"},{\"id\":\"4138\",\"type\":\"GlyphRenderer\"},{\"id\":\"4142\",\"type\":\"GlyphRenderer\"},{\"id\":\"4146\",\"type\":\"GlyphRenderer\"},{\"id\":\"4150\",\"type\":\"GlyphRenderer\"},{\"id\":\"4154\",\"type\":\"GlyphRenderer\"},{\"id\":\"4158\",\"type\":\"GlyphRenderer\"},{\"id\":\"4162\",\"type\":\"GlyphRenderer\"},{\"id\":\"4166\",\"type\":\"GlyphRenderer\"},{\"id\":\"4170\",\"type\":\"GlyphRenderer\"},{\"id\":\"4174\",\"type\":\"GlyphRenderer\"},{\"id\":\"4178\",\"type\":\"GlyphRenderer\"},{\"id\":\"4182\",\"type\":\"GlyphRenderer\"},{\"id\":\"4186\",\"type\":\"GlyphRenderer\"},{\"id\":\"4190\",\"type\":\"GlyphRenderer\"},{\"id\":\"4194\",\"type\":\"GlyphRenderer\"},{\"id\":\"4198\",\"type\":\"GlyphRenderer\"},{\"id\":\"4202\",\"type\":\"GlyphRenderer\"},{\"id\":\"4206\",\"type\":\"GlyphRenderer\"},{\"id\":\"4210\",\"type\":\"GlyphRenderer\"},{\"id\":\"4214\",\"type\":\"GlyphRenderer\"},{\"id\":\"4218\",\"type\":\"GlyphRenderer\"},{\"id\":\"4222\",\"type\":\"GlyphRenderer\"},{\"id\":\"4226\",\"type\":\"GlyphRenderer\"},{\"id\":\"4230\",\"type\":\"GlyphRenderer\"}],\"right\":[{\"id\":\"1052\",\"type\":\"ColorBar\"}],\"title\":{\"id\":\"1039\",\"type\":\"Title\"},\"toolbar\":{\"id\":\"1034\",\"type\":\"Toolbar\"},\"x_range\":{\"id\":\"1012\",\"type\":\"Range1d\"},\"x_scale\":{\"id\":\"1016\",\"type\":\"LinearScale\"},\"y_range\":{\"id\":\"1014\",\"type\":\"Range1d\"},\"y_scale\":{\"id\":\"1018\",\"type\":\"LinearScale\"}},\"id\":\"1011\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"attributes\":{\"data_source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1645\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1646\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1591\",\"type\":\"CDSView\"}},\"id\":\"1647\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4168\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4169\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4059\",\"type\":\"CDSView\"}},\"id\":\"4170\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2600\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2933\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"1167\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"filters\":[{\"id\":\"1876\",\"type\":\"GroupFilter\"},{\"id\":\"1877\",\"type\":\"GroupFilter\"},{\"id\":\"1878\",\"type\":\"GroupFilter\"},{\"id\":\"1879\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"}},\"id\":\"1880\",\"type\":\"CDSView\"},{\"attributes\":{\"data_source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1673\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1674\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1626\",\"type\":\"CDSView\"}},\"id\":\"1675\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"1353\",\"type\":\"GroupFilter\"},{\"id\":\"1354\",\"type\":\"GroupFilter\"},{\"id\":\"1355\",\"type\":\"GroupFilter\"},{\"id\":\"1356\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"}},\"id\":\"1357\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2601\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2934\",\"type\":\"Scatter\"},{\"attributes\":{\"bottom_units\":\"screen\",\"fill_alpha\":{\"value\":0.5},\"fill_color\":{\"value\":\"lightgrey\"},\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":{\"value\":1.0},\"line_color\":{\"value\":\"black\"},\"line_dash\":[4,4],\"line_width\":{\"value\":2},\"render_mode\":\"css\",\"right_units\":\"screen\",\"top_units\":\"screen\"},\"id\":\"1169\",\"type\":\"BoxAnnotation\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1071\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1861\",\"type\":\"GroupFilter\"},{\"id\":\"1862\",\"type\":\"GroupFilter\"},{\"id\":\"1863\",\"type\":\"GroupFilter\"},{\"id\":\"1864\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"}},\"id\":\"1865\",\"type\":\"CDSView\"},{\"attributes\":{\"data_source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2600\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2601\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2553\",\"type\":\"CDSView\"}},\"id\":\"2602\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1649\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4172\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2933\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2934\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2882\",\"type\":\"CDSView\"}},\"id\":\"2935\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"1069\",\"type\":\"GroupFilter\"},{\"id\":\"1070\",\"type\":\"GroupFilter\"},{\"id\":\"1071\",\"type\":\"GroupFilter\"},{\"id\":\"1072\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"}},\"id\":\"1073\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1170\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1650\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4173\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"1171\",\"type\":\"Selection\"},{\"attributes\":{\"booleans\":[true,true,true,true,true]},\"id\":\"1869\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"text\":\"\",\"text_font_size\":{\"value\":\"15pt\"}},\"id\":\"1039\",\"type\":\"Title\"},{\"attributes\":{\"data_source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2941\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2942\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2892\",\"type\":\"CDSView\"}},\"id\":\"2943\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"1074\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1649\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1650\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1596\",\"type\":\"CDSView\"}},\"id\":\"1651\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4172\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4173\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4064\",\"type\":\"CDSView\"}},\"id\":\"4174\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2604\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"1172\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"1359\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1360\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true]},\"id\":\"1879\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4192\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4193\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4089\",\"type\":\"CDSView\"}},\"id\":\"4194\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1674\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2605\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"3621\",\"type\":\"GroupFilter\"},{\"id\":\"3622\",\"type\":\"GroupFilter\"},{\"id\":\"3623\",\"type\":\"GroupFilter\"},{\"id\":\"3624\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"}},\"id\":\"3625\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2945\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"1173\",\"type\":\"Selection\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"1075\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2604\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2605\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2558\",\"type\":\"CDSView\"}},\"id\":\"2606\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1653\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4176\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"1174\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"filters\":[{\"id\":\"1358\",\"type\":\"GroupFilter\"},{\"id\":\"1359\",\"type\":\"GroupFilter\"},{\"id\":\"1360\",\"type\":\"GroupFilter\"},{\"id\":\"1361\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"}},\"id\":\"1362\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2946\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1076\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1654\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4177\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"1175\",\"type\":\"Selection\"},{\"attributes\":{\"booleans\":[true,true]},\"id\":\"1077\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2945\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2946\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2897\",\"type\":\"CDSView\"}},\"id\":\"2947\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"booleans\":[true,true,true,true,true]},\"id\":\"1884\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"3627\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1653\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1654\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1601\",\"type\":\"CDSView\"}},\"id\":\"1655\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4176\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4177\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4069\",\"type\":\"CDSView\"}},\"id\":\"4178\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"1074\",\"type\":\"GroupFilter\"},{\"id\":\"1075\",\"type\":\"GroupFilter\"},{\"id\":\"1076\",\"type\":\"GroupFilter\"},{\"id\":\"1077\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"}},\"id\":\"1078\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1364\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"1303\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"1304\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"3218\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1673\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4193\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"1079\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3628\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1365\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2949\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"3629\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1657\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4180\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1364\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1365\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1307\",\"type\":\"CDSView\"}},\"id\":\"1366\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2950\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"3626\",\"type\":\"GroupFilter\"},{\"id\":\"3627\",\"type\":\"GroupFilter\"},{\"id\":\"3628\",\"type\":\"GroupFilter\"},{\"id\":\"3629\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"}},\"id\":\"3630\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1658\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4181\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"1080\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true]},\"id\":\"1874\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2949\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2950\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2902\",\"type\":\"CDSView\"}},\"id\":\"2951\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1081\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"1572\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1657\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1658\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1606\",\"type\":\"CDSView\"}},\"id\":\"1659\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4180\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4181\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4074\",\"type\":\"CDSView\"}},\"id\":\"4182\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"1867\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"1872\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1368\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true]},\"id\":\"1082\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"1871\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4192\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"3632\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1079\",\"type\":\"GroupFilter\"},{\"id\":\"1080\",\"type\":\"GroupFilter\"},{\"id\":\"1081\",\"type\":\"GroupFilter\"},{\"id\":\"1082\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"}},\"id\":\"1083\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1369\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2953\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"1881\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"2530\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4023\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"4081\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1404\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1405\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1357\",\"type\":\"CDSView\"}},\"id\":\"1406\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"4030\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2536\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"20\"},\"id\":\"4082\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4083\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1408\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"4080\",\"type\":\"GroupFilter\"},{\"id\":\"4081\",\"type\":\"GroupFilter\"},{\"id\":\"4082\",\"type\":\"GroupFilter\"},{\"id\":\"4083\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4084\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1409\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"2535\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"4085\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1408\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1409\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1362\",\"type\":\"CDSView\"}},\"id\":\"1410\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2511\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"4031\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"4045\",\"type\":\"GroupFilter\"},{\"id\":\"4046\",\"type\":\"GroupFilter\"},{\"id\":\"4047\",\"type\":\"GroupFilter\"},{\"id\":\"4048\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4049\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"4086\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"4050\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"4087\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2531\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"2534\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4088\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"4085\",\"type\":\"GroupFilter\"},{\"id\":\"4086\",\"type\":\"GroupFilter\"},{\"id\":\"4087\",\"type\":\"GroupFilter\"},{\"id\":\"4088\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4089\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true]},\"id\":\"2532\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"20\"},\"id\":\"4022\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4028\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"4090\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"3619\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"2514\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"4025\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"4091\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"4020\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"20\"},\"id\":\"4092\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"3637\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"4020\",\"type\":\"GroupFilter\"},{\"id\":\"4021\",\"type\":\"GroupFilter\"},{\"id\":\"4022\",\"type\":\"GroupFilter\"},{\"id\":\"4023\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4024\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true]},\"id\":\"2517\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"2509\",\"type\":\"GroupFilter\"},{\"id\":\"2510\",\"type\":\"GroupFilter\"},{\"id\":\"2511\",\"type\":\"GroupFilter\"},{\"id\":\"2512\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"}},\"id\":\"2513\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4093\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"red\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"orange\",\"white\",\"white\",\"white\",\"white\",\"white\"],\"origin\":[\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\"],\"p_delay\":[\"None\",\"None\",\"None\",\"None\",1,1,1,1,2,2,2,2,4,4,4,4,8,8,8,8],\"p_sequence_length\":[1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4],\"runs\":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],\"size\":[12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,36.0,12.0,12.0,12.0,12.0,12.0],\"type\":[\"Final Incumbent\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Default\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\"],\"x\":{\"__ndarray__\":\"9XycTryI4z8V1Y/pH4nVP33uZXS0Jq8/nYRVUx7zyL/jng7jxhThP6T+EOPF7tA/ZyIjRMDzOT9NoCikMQ/Pv52J5DpVYt4/vIle97OdyT9U/iO4yVyyv9fmb0ChoNS/bHPta/FD1z83ME5yQuCzP6CN+1CCs8y/eNa9Cfav37+8/kuUsG+2P00m6FDdzca/LRUVBt7n37+U8N/D7grpvw==\",\"dtype\":\"float64\",\"shape\":[20]},\"y\":{\"__ndarray__\":\"mzBNdScfwr/cguHH3HPRv8eNZF3Badu/c7FyYAoG47/ygmwPQ8SivzX5O1I4IcS/mkKm6HCl078HiqO8Tmrev+mQWWh3ybc/XU2yO8n9oL+KgUkYMf7Hv/TTqU536ta/ePHIKFAr1z/sli0p0TnMP82toUqzZ6k/jc+90/Xiv79FLDzKq2nrP/fU5FUHweU/ABKfywWy3z9fTLA7OAXXPw==\",\"dtype\":\"float64\",\"shape\":[20]},\"zorder\":[\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"20\",\"0\",\"0\",\"0\",\"0\",\"0\"]},\"selected\":{\"id\":\"4262\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"4261\",\"type\":\"UnionRenderers\"}},\"id\":\"1010\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"filters\":[{\"id\":\"4090\",\"type\":\"GroupFilter\"},{\"id\":\"4091\",\"type\":\"GroupFilter\"},{\"id\":\"4092\",\"type\":\"GroupFilter\"},{\"id\":\"4093\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4094\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"2505\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true]},\"id\":\"2507\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"2504\",\"type\":\"GroupFilter\"},{\"id\":\"2505\",\"type\":\"GroupFilter\"},{\"id\":\"2506\",\"type\":\"GroupFilter\"},{\"id\":\"2507\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"}},\"id\":\"2508\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"20\"},\"id\":\"4032\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"4095\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2516\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"4025\",\"type\":\"GroupFilter\"},{\"id\":\"4026\",\"type\":\"GroupFilter\"},{\"id\":\"4027\",\"type\":\"GroupFilter\"},{\"id\":\"4028\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4029\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2506\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"4021\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"4096\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4033\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"3636\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1574\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"4026\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"4097\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"1578\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"2515\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4048\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1582\",\"type\":\"GroupFilter\"},{\"id\":\"1583\",\"type\":\"GroupFilter\"},{\"id\":\"1584\",\"type\":\"GroupFilter\"},{\"id\":\"1585\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"}},\"id\":\"1586\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2521\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4098\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1661\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"4015\",\"type\":\"GroupFilter\"},{\"id\":\"4016\",\"type\":\"GroupFilter\"},{\"id\":\"4017\",\"type\":\"GroupFilter\"},{\"id\":\"4018\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4019\",\"type\":\"CDSView\"},{\"attributes\":{\"filters\":[{\"id\":\"4095\",\"type\":\"GroupFilter\"},{\"id\":\"4096\",\"type\":\"GroupFilter\"},{\"id\":\"4097\",\"type\":\"GroupFilter\"},{\"id\":\"4098\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4099\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"2520\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"4027\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"4030\",\"type\":\"GroupFilter\"},{\"id\":\"4031\",\"type\":\"GroupFilter\"},{\"id\":\"4032\",\"type\":\"GroupFilter\"},{\"id\":\"4033\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4034\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"4100\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"1882\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"2519\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"4035\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"4101\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"2514\",\"type\":\"GroupFilter\"},{\"id\":\"2515\",\"type\":\"GroupFilter\"},{\"id\":\"2516\",\"type\":\"GroupFilter\"},{\"id\":\"2517\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"}},\"id\":\"2518\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true,true]},\"id\":\"1580\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"4036\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"20\"},\"id\":\"4102\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"1582\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true]},\"id\":\"2512\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true]},\"id\":\"2522\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"4037\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4103\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true]},\"id\":\"1575\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"2529\",\"type\":\"GroupFilter\"},{\"id\":\"2530\",\"type\":\"GroupFilter\"},{\"id\":\"2531\",\"type\":\"GroupFilter\"},{\"id\":\"2532\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"}},\"id\":\"2533\",\"type\":\"CDSView\"},{\"attributes\":{\"filters\":[{\"id\":\"4100\",\"type\":\"GroupFilter\"},{\"id\":\"4101\",\"type\":\"GroupFilter\"},{\"id\":\"4102\",\"type\":\"GroupFilter\"},{\"id\":\"4103\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4104\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4038\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1577\",\"type\":\"GroupFilter\"},{\"id\":\"1578\",\"type\":\"GroupFilter\"},{\"id\":\"1579\",\"type\":\"GroupFilter\"},{\"id\":\"1580\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"}},\"id\":\"1581\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"2510\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"4035\",\"type\":\"GroupFilter\"},{\"id\":\"4036\",\"type\":\"GroupFilter\"},{\"id\":\"4037\",\"type\":\"GroupFilter\"},{\"id\":\"4038\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4039\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1579\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"4105\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"2509\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"1877\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3648\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"1573\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"4040\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"4106\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"3654\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true]},\"id\":\"1585\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"4041\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"4107\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"2519\",\"type\":\"GroupFilter\"},{\"id\":\"2520\",\"type\":\"GroupFilter\"},{\"id\":\"2521\",\"type\":\"GroupFilter\"},{\"id\":\"2522\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"}},\"id\":\"2523\",\"type\":\"CDSView\"},{\"attributes\":{\"filters\":[{\"id\":\"2524\",\"type\":\"GroupFilter\"},{\"id\":\"2525\",\"type\":\"GroupFilter\"},{\"id\":\"2526\",\"type\":\"GroupFilter\"},{\"id\":\"2527\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"}},\"id\":\"2528\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"20\"},\"id\":\"4042\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4108\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"1587\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"4105\",\"type\":\"GroupFilter\"},{\"id\":\"4106\",\"type\":\"GroupFilter\"},{\"id\":\"4107\",\"type\":\"GroupFilter\"},{\"id\":\"4108\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4109\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"2529\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4043\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"4040\",\"type\":\"GroupFilter\"},{\"id\":\"4041\",\"type\":\"GroupFilter\"},{\"id\":\"4042\",\"type\":\"GroupFilter\"},{\"id\":\"4043\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4044\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2526\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"4110\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1584\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"3634\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"4045\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"1583\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"4111\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"2524\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1572\",\"type\":\"GroupFilter\"},{\"id\":\"1573\",\"type\":\"GroupFilter\"},{\"id\":\"1574\",\"type\":\"GroupFilter\"},{\"id\":\"1575\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"}},\"id\":\"1576\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true]},\"id\":\"1072\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"4046\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"20\"},\"id\":\"4112\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"1577\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true]},\"id\":\"2527\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"4047\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4113\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"2525\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3310\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3311\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3261\",\"type\":\"CDSView\"}},\"id\":\"3312\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true]},\"id\":\"2537\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"3649\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1115\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1116\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1058\",\"type\":\"CDSView\"}},\"id\":\"1117\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3684\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"1597\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"2534\",\"type\":\"GroupFilter\"},{\"id\":\"2535\",\"type\":\"GroupFilter\"},{\"id\":\"2536\",\"type\":\"GroupFilter\"},{\"id\":\"2537\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"}},\"id\":\"2538\",\"type\":\"CDSView\"},{\"attributes\":{\"filters\":[{\"id\":\"3646\",\"type\":\"GroupFilter\"},{\"id\":\"3647\",\"type\":\"GroupFilter\"},{\"id\":\"3648\",\"type\":\"GroupFilter\"},{\"id\":\"3649\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"}},\"id\":\"3650\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"2216\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3683\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3684\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3630\",\"type\":\"CDSView\"}},\"id\":\"3685\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"1592\",\"type\":\"GroupFilter\"},{\"id\":\"1593\",\"type\":\"GroupFilter\"},{\"id\":\"1594\",\"type\":\"GroupFilter\"},{\"id\":\"1595\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"}},\"id\":\"1596\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2217\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3314\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"1598\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"2539\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"3651\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1119\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3700\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true]},\"id\":\"2218\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3315\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1120\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"2215\",\"type\":\"GroupFilter\"},{\"id\":\"2216\",\"type\":\"GroupFilter\"},{\"id\":\"2217\",\"type\":\"GroupFilter\"},{\"id\":\"2218\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"}},\"id\":\"2219\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3687\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3314\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3315\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3266\",\"type\":\"CDSView\"}},\"id\":\"3316\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1599\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"2540\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"3652\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1119\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1120\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1063\",\"type\":\"CDSView\"}},\"id\":\"1121\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3688\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"2220\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true]},\"id\":\"1600\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2541\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"3646\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3653\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3687\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3688\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3635\",\"type\":\"CDSView\"}},\"id\":\"3689\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"1597\",\"type\":\"GroupFilter\"},{\"id\":\"1598\",\"type\":\"GroupFilter\"},{\"id\":\"1599\",\"type\":\"GroupFilter\"},{\"id\":\"1600\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"}},\"id\":\"1601\",\"type\":\"CDSView\"},{\"attributes\":{\"filters\":[{\"id\":\"3636\",\"type\":\"GroupFilter\"},{\"id\":\"3637\",\"type\":\"GroupFilter\"},{\"id\":\"3638\",\"type\":\"GroupFilter\"},{\"id\":\"3639\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"}},\"id\":\"3640\",\"type\":\"CDSView\"},{\"attributes\":{\"data_source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1131\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1132\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1078\",\"type\":\"CDSView\"}},\"id\":\"1133\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3318\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"2221\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true]},\"id\":\"2542\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1123\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"2539\",\"type\":\"GroupFilter\"},{\"id\":\"2540\",\"type\":\"GroupFilter\"},{\"id\":\"2541\",\"type\":\"GroupFilter\"},{\"id\":\"2542\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"}},\"id\":\"2543\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3699\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3319\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"3651\",\"type\":\"GroupFilter\"},{\"id\":\"3652\",\"type\":\"GroupFilter\"},{\"id\":\"3653\",\"type\":\"GroupFilter\"},{\"id\":\"3654\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"}},\"id\":\"3655\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"1603\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2222\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1124\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3691\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1604\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3318\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3319\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3271\",\"type\":\"CDSView\"}},\"id\":\"3320\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true]},\"id\":\"2223\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"2544\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"3656\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1123\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1124\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1068\",\"type\":\"CDSView\"}},\"id\":\"1125\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3692\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"1602\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"2220\",\"type\":\"GroupFilter\"},{\"id\":\"2221\",\"type\":\"GroupFilter\"},{\"id\":\"2222\",\"type\":\"GroupFilter\"},{\"id\":\"2223\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"}},\"id\":\"2224\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"2545\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"3642\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"3657\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3691\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3692\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3640\",\"type\":\"CDSView\"}},\"id\":\"3693\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1132\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true]},\"id\":\"1605\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3322\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"2225\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2546\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"3617\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3699\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3700\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3650\",\"type\":\"CDSView\"}},\"id\":\"3701\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1127\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"1602\",\"type\":\"GroupFilter\"},{\"id\":\"1603\",\"type\":\"GroupFilter\"},{\"id\":\"1604\",\"type\":\"GroupFilter\"},{\"id\":\"1605\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"}},\"id\":\"1606\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3323\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true]},\"id\":\"2547\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"3621\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"3659\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1128\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"2226\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"4016\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3322\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3323\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3276\",\"type\":\"CDSView\"}},\"id\":\"3324\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"1607\",\"type\":\"GroupFilter\"},{\"id\":\"1608\",\"type\":\"GroupFilter\"},{\"id\":\"1609\",\"type\":\"GroupFilter\"},{\"id\":\"1610\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"}},\"id\":\"1611\",\"type\":\"CDSView\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"red\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\"],\"origin\":[\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\"],\"p_delay\":[\"None\",\"None\",\"None\",\"None\",1,1,1],\"p_sequence_length\":[1,2,3,4,1,2,3],\"runs\":[1,1,1,1,1,1,1],\"size\":[12.0,12.0,12.0,12.0,12.0,12.0,12.0],\"type\":[\"Final Incumbent\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\"],\"x\":{\"__ndarray__\":\"9XycTryI4z8V1Y/pH4nVP33uZXS0Jq8/nYRVUx7zyL/jng7jxhThP6T+EOPF7tA/ZyIjRMDzOT8=\",\"dtype\":\"float64\",\"shape\":[7]},\"y\":{\"__ndarray__\":\"mzBNdScfwr/cguHH3HPRv8eNZF3Badu/c7FyYAoG47/ygmwPQ8SivzX5O1I4IcS/mkKm6HCl078=\",\"dtype\":\"float64\",\"shape\":[7]},\"zorder\":[\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\"]},\"selected\":{\"id\":\"2630\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"2629\",\"type\":\"UnionRenderers\"}},\"id\":\"1006\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"filters\":[{\"id\":\"2544\",\"type\":\"GroupFilter\"},{\"id\":\"2545\",\"type\":\"GroupFilter\"},{\"id\":\"2546\",\"type\":\"GroupFilter\"},{\"id\":\"2547\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"}},\"id\":\"2548\",\"type\":\"CDSView\"},{\"attributes\":{\"data_source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1127\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1128\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1073\",\"type\":\"CDSView\"}},\"id\":\"1129\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3703\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"3656\",\"type\":\"GroupFilter\"},{\"id\":\"3657\",\"type\":\"GroupFilter\"},{\"id\":\"3658\",\"type\":\"GroupFilter\"},{\"id\":\"3659\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"}},\"id\":\"3660\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true,true]},\"id\":\"1610\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2227\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"2549\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"3661\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1131\",\"type\":\"Scatter\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"red\",\"white\",\"white\",\"white\",\"white\",\"white\"],\"origin\":[\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\"],\"p_delay\":[\"None\",\"None\",\"None\",\"None\",1,1],\"p_sequence_length\":[1,2,3,4,1,2],\"runs\":[1,1,1,1,1,1],\"size\":[12.0,12.0,12.0,12.0,12.0,12.0],\"type\":[\"Final Incumbent\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\"],\"x\":{\"__ndarray__\":\"9XycTryI4z8V1Y/pH4nVP33uZXS0Jq8/nYRVUx7zyL/jng7jxhThP6T+EOPF7tA/\",\"dtype\":\"float64\",\"shape\":[6]},\"y\":{\"__ndarray__\":\"mzBNdScfwr/cguHH3HPRv8eNZF3Badu/c7FyYAoG47/ygmwPQ8SivzX5O1I4IcS/\",\"dtype\":\"float64\",\"shape\":[6]},\"zorder\":[\"0\",\"0\",\"0\",\"0\",\"0\",\"0\"]},\"selected\":{\"id\":\"2299\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"2298\",\"type\":\"UnionRenderers\"}},\"id\":\"1005\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3704\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1609\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true]},\"id\":\"2228\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3658\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3703\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3704\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3655\",\"type\":\"CDSView\"}},\"id\":\"3705\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1135\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"2225\",\"type\":\"GroupFilter\"},{\"id\":\"2226\",\"type\":\"GroupFilter\"},{\"id\":\"2227\",\"type\":\"GroupFilter\"},{\"id\":\"2228\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"}},\"id\":\"2229\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"1608\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"2550\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"3662\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1136\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2263\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2551\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2231\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"1607\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3663\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"4015\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1135\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1136\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1083\",\"type\":\"CDSView\"}},\"id\":\"1137\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3707\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1863\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"1612\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true]},\"id\":\"2552\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"3664\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2232\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"2549\",\"type\":\"GroupFilter\"},{\"id\":\"2550\",\"type\":\"GroupFilter\"},{\"id\":\"2551\",\"type\":\"GroupFilter\"},{\"id\":\"2552\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"}},\"id\":\"2553\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3708\",\"type\":\"Scatter\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"red\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\"],\"origin\":[\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\"],\"p_delay\":[\"None\",\"None\",\"None\",\"None\",1,1,1,1,2,2],\"p_sequence_length\":[1,2,3,4,1,2,3,4,1,2],\"runs\":[1,1,1,1,1,1,1,1,1,1],\"size\":[12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0],\"type\":[\"Final Incumbent\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\"],\"x\":{\"__ndarray__\":\"9XycTryI4z8V1Y/pH4nVP33uZXS0Jq8/nYRVUx7zyL/jng7jxhThP6T+EOPF7tA/ZyIjRMDzOT9NoCikMQ/Pv52J5DpVYt4/vIle97OdyT8=\",\"dtype\":\"float64\",\"shape\":[10]},\"y\":{\"__ndarray__\":\"mzBNdScfwr/cguHH3HPRv8eNZF3Badu/c7FyYAoG47/ygmwPQ8SivzX5O1I4IcS/mkKm6HCl078HiqO8Tmrev+mQWWh3ybc/XU2yO8n9oL8=\",\"dtype\":\"float64\",\"shape\":[10]},\"zorder\":[\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\"]},\"selected\":{\"id\":\"3352\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"3351\",\"type\":\"UnionRenderers\"}},\"id\":\"1008\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"filters\":[{\"id\":\"3661\",\"type\":\"GroupFilter\"},{\"id\":\"3662\",\"type\":\"GroupFilter\"},{\"id\":\"3663\",\"type\":\"GroupFilter\"},{\"id\":\"3664\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"}},\"id\":\"3665\",\"type\":\"CDSView\"},{\"attributes\":{\"data_source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2231\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2232\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2174\",\"type\":\"CDSView\"}},\"id\":\"2233\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3707\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3708\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3660\",\"type\":\"CDSView\"}},\"id\":\"3709\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1139\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3667\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1614\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"2554\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1140\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true]},\"id\":\"1615\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"4017\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"2504\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"2555\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1883\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4018\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1139\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1140\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1088\",\"type\":\"CDSView\"}},\"id\":\"1141\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2235\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3668\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3711\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"1613\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2556\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"3607\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3667\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3668\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3610\",\"type\":\"CDSView\"}},\"id\":\"3669\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2236\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3712\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true]},\"id\":\"2557\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2235\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2236\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2179\",\"type\":\"CDSView\"}},\"id\":\"2237\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3711\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3712\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3665\",\"type\":\"CDSView\"}},\"id\":\"3713\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1143\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"1612\",\"type\":\"GroupFilter\"},{\"id\":\"1613\",\"type\":\"GroupFilter\"},{\"id\":\"1614\",\"type\":\"GroupFilter\"},{\"id\":\"1615\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"}},\"id\":\"1616\",\"type\":\"CDSView\"},{\"attributes\":{\"filters\":[{\"id\":\"2554\",\"type\":\"GroupFilter\"},{\"id\":\"2555\",\"type\":\"GroupFilter\"},{\"id\":\"2556\",\"type\":\"GroupFilter\"},{\"id\":\"2557\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"}},\"id\":\"2558\",\"type\":\"CDSView\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"red\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\"],\"origin\":[\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\"],\"p_delay\":[\"None\",\"None\",\"None\",\"None\",1,1,1,1],\"p_sequence_length\":[1,2,3,4,1,2,3,4],\"runs\":[1,1,1,1,1,1,1,1],\"size\":[12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0],\"type\":[\"Final Incumbent\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\"],\"x\":{\"__ndarray__\":\"9XycTryI4z8V1Y/pH4nVP33uZXS0Jq8/nYRVUx7zyL/jng7jxhThP6T+EOPF7tA/ZyIjRMDzOT9NoCikMQ/Pvw==\",\"dtype\":\"float64\",\"shape\":[8]},\"y\":{\"__ndarray__\":\"mzBNdScfwr/cguHH3HPRv8eNZF3Badu/c7FyYAoG47/ygmwPQ8SivzX5O1I4IcS/mkKm6HCl078HiqO8Tmrevw==\",\"dtype\":\"float64\",\"shape\":[8]},\"zorder\":[\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\"]},\"selected\":{\"id\":\"2981\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"2980\",\"type\":\"UnionRenderers\"}},\"id\":\"1007\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"data_source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2259\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2260\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2209\",\"type\":\"CDSView\"}},\"id\":\"2261\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1144\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3671\",\"type\":\"Scatter\"},{\"attributes\":{\"callback\":null,\"renderers\":[{\"id\":\"1117\",\"type\":\"GlyphRenderer\"},{\"id\":\"1121\",\"type\":\"GlyphRenderer\"},{\"id\":\"1125\",\"type\":\"GlyphRenderer\"},{\"id\":\"1129\",\"type\":\"GlyphRenderer\"},{\"id\":\"1133\",\"type\":\"GlyphRenderer\"},{\"id\":\"1137\",\"type\":\"GlyphRenderer\"},{\"id\":\"1141\",\"type\":\"GlyphRenderer\"},{\"id\":\"1145\",\"type\":\"GlyphRenderer\"},{\"id\":\"1149\",\"type\":\"GlyphRenderer\"},{\"id\":\"1153\",\"type\":\"GlyphRenderer\"},{\"id\":\"1157\",\"type\":\"GlyphRenderer\"},{\"id\":\"1161\",\"type\":\"GlyphRenderer\"},{\"id\":\"1366\",\"type\":\"GlyphRenderer\"},{\"id\":\"1370\",\"type\":\"GlyphRenderer\"},{\"id\":\"1374\",\"type\":\"GlyphRenderer\"},{\"id\":\"1378\",\"type\":\"GlyphRenderer\"},{\"id\":\"1382\",\"type\":\"GlyphRenderer\"},{\"id\":\"1386\",\"type\":\"GlyphRenderer\"},{\"id\":\"1390\",\"type\":\"GlyphRenderer\"},{\"id\":\"1394\",\"type\":\"GlyphRenderer\"},{\"id\":\"1398\",\"type\":\"GlyphRenderer\"},{\"id\":\"1402\",\"type\":\"GlyphRenderer\"},{\"id\":\"1406\",\"type\":\"GlyphRenderer\"},{\"id\":\"1410\",\"type\":\"GlyphRenderer\"},{\"id\":\"1635\",\"type\":\"GlyphRenderer\"},{\"id\":\"1639\",\"type\":\"GlyphRenderer\"},{\"id\":\"1643\",\"type\":\"GlyphRenderer\"},{\"id\":\"1647\",\"type\":\"GlyphRenderer\"},{\"id\":\"1651\",\"type\":\"GlyphRenderer\"},{\"id\":\"1655\",\"type\":\"GlyphRenderer\"},{\"id\":\"1659\",\"type\":\"GlyphRenderer\"},{\"id\":\"1663\",\"type\":\"GlyphRenderer\"},{\"id\":\"1667\",\"type\":\"GlyphRenderer\"},{\"id\":\"1671\",\"type\":\"GlyphRenderer\"},{\"id\":\"1675\",\"type\":\"GlyphRenderer\"},{\"id\":\"1679\",\"type\":\"GlyphRenderer\"},{\"id\":\"1924\",\"type\":\"GlyphRenderer\"},{\"id\":\"1928\",\"type\":\"GlyphRenderer\"},{\"id\":\"1932\",\"type\":\"GlyphRenderer\"},{\"id\":\"1936\",\"type\":\"GlyphRenderer\"},{\"id\":\"1940\",\"type\":\"GlyphRenderer\"},{\"id\":\"1944\",\"type\":\"GlyphRenderer\"},{\"id\":\"1948\",\"type\":\"GlyphRenderer\"},{\"id\":\"1952\",\"type\":\"GlyphRenderer\"},{\"id\":\"1956\",\"type\":\"GlyphRenderer\"},{\"id\":\"1960\",\"type\":\"GlyphRenderer\"},{\"id\":\"1964\",\"type\":\"GlyphRenderer\"},{\"id\":\"1968\",\"type\":\"GlyphRenderer\"},{\"id\":\"2233\",\"type\":\"GlyphRenderer\"},{\"id\":\"2237\",\"type\":\"GlyphRenderer\"},{\"id\":\"2241\",\"type\":\"GlyphRenderer\"},{\"id\":\"2245\",\"type\":\"GlyphRenderer\"},{\"id\":\"2249\",\"type\":\"GlyphRenderer\"},{\"id\":\"2253\",\"type\":\"GlyphRenderer\"},{\"id\":\"2257\",\"type\":\"GlyphRenderer\"},{\"id\":\"2261\",\"type\":\"GlyphRenderer\"},{\"id\":\"2265\",\"type\":\"GlyphRenderer\"},{\"id\":\"2269\",\"type\":\"GlyphRenderer\"},{\"id\":\"2273\",\"type\":\"GlyphRenderer\"},{\"id\":\"2277\",\"type\":\"GlyphRenderer\"},{\"id\":\"2562\",\"type\":\"GlyphRenderer\"},{\"id\":\"2566\",\"type\":\"GlyphRenderer\"},{\"id\":\"2570\",\"type\":\"GlyphRenderer\"},{\"id\":\"2574\",\"type\":\"GlyphRenderer\"},{\"id\":\"2578\",\"type\":\"GlyphRenderer\"},{\"id\":\"2582\",\"type\":\"GlyphRenderer\"},{\"id\":\"2586\",\"type\":\"GlyphRenderer\"},{\"id\":\"2590\",\"type\":\"GlyphRenderer\"},{\"id\":\"2594\",\"type\":\"GlyphRenderer\"},{\"id\":\"2598\",\"type\":\"GlyphRenderer\"},{\"id\":\"2602\",\"type\":\"GlyphRenderer\"},{\"id\":\"2606\",\"type\":\"GlyphRenderer\"},{\"id\":\"2911\",\"type\":\"GlyphRenderer\"},{\"id\":\"2915\",\"type\":\"GlyphRenderer\"},{\"id\":\"2919\",\"type\":\"GlyphRenderer\"},{\"id\":\"2923\",\"type\":\"GlyphRenderer\"},{\"id\":\"2927\",\"type\":\"GlyphRenderer\"},{\"id\":\"2931\",\"type\":\"GlyphRenderer\"},{\"id\":\"2935\",\"type\":\"GlyphRenderer\"},{\"id\":\"2939\",\"type\":\"GlyphRenderer\"},{\"id\":\"2943\",\"type\":\"GlyphRenderer\"},{\"id\":\"2947\",\"type\":\"GlyphRenderer\"},{\"id\":\"2951\",\"type\":\"GlyphRenderer\"},{\"id\":\"2955\",\"type\":\"GlyphRenderer\"},{\"id\":\"3280\",\"type\":\"GlyphRenderer\"},{\"id\":\"3284\",\"type\":\"GlyphRenderer\"},{\"id\":\"3288\",\"type\":\"GlyphRenderer\"},{\"id\":\"3292\",\"type\":\"GlyphRenderer\"},{\"id\":\"3296\",\"type\":\"GlyphRenderer\"},{\"id\":\"3300\",\"type\":\"GlyphRenderer\"},{\"id\":\"3304\",\"type\":\"GlyphRenderer\"},{\"id\":\"3308\",\"type\":\"GlyphRenderer\"},{\"id\":\"3312\",\"type\":\"GlyphRenderer\"},{\"id\":\"3316\",\"type\":\"GlyphRenderer\"},{\"id\":\"3320\",\"type\":\"GlyphRenderer\"},{\"id\":\"3324\",\"type\":\"GlyphRenderer\"},{\"id\":\"3669\",\"type\":\"GlyphRenderer\"},{\"id\":\"3673\",\"type\":\"GlyphRenderer\"},{\"id\":\"3677\",\"type\":\"GlyphRenderer\"},{\"id\":\"3681\",\"type\":\"GlyphRenderer\"},{\"id\":\"3685\",\"type\":\"GlyphRenderer\"},{\"id\":\"3689\",\"type\":\"GlyphRenderer\"},{\"id\":\"3693\",\"type\":\"GlyphRenderer\"},{\"id\":\"3697\",\"type\":\"GlyphRenderer\"},{\"id\":\"3701\",\"type\":\"GlyphRenderer\"},{\"id\":\"3705\",\"type\":\"GlyphRenderer\"},{\"id\":\"3709\",\"type\":\"GlyphRenderer\"},{\"id\":\"3713\",\"type\":\"GlyphRenderer\"},{\"id\":\"4138\",\"type\":\"GlyphRenderer\"},{\"id\":\"4142\",\"type\":\"GlyphRenderer\"},{\"id\":\"4146\",\"type\":\"GlyphRenderer\"},{\"id\":\"4150\",\"type\":\"GlyphRenderer\"},{\"id\":\"4154\",\"type\":\"GlyphRenderer\"},{\"id\":\"4158\",\"type\":\"GlyphRenderer\"},{\"id\":\"4162\",\"type\":\"GlyphRenderer\"},{\"id\":\"4166\",\"type\":\"GlyphRenderer\"},{\"id\":\"4170\",\"type\":\"GlyphRenderer\"},{\"id\":\"4174\",\"type\":\"GlyphRenderer\"},{\"id\":\"4178\",\"type\":\"GlyphRenderer\"},{\"id\":\"4182\",\"type\":\"GlyphRenderer\"},{\"id\":\"4186\",\"type\":\"GlyphRenderer\"},{\"id\":\"4190\",\"type\":\"GlyphRenderer\"},{\"id\":\"4194\",\"type\":\"GlyphRenderer\"},{\"id\":\"4198\",\"type\":\"GlyphRenderer\"},{\"id\":\"4202\",\"type\":\"GlyphRenderer\"},{\"id\":\"4206\",\"type\":\"GlyphRenderer\"},{\"id\":\"4210\",\"type\":\"GlyphRenderer\"},{\"id\":\"4214\",\"type\":\"GlyphRenderer\"},{\"id\":\"4218\",\"type\":\"GlyphRenderer\"},{\"id\":\"4222\",\"type\":\"GlyphRenderer\"},{\"id\":\"4226\",\"type\":\"GlyphRenderer\"},{\"id\":\"4230\",\"type\":\"GlyphRenderer\"}],\"tooltips\":[[\"type\",\"@type\"],[\"origin\",\"@origin\"],[\"runs\",\"@runs\"],[\"delay\",\"@p_delay\"],[\"sequence_length\",\"@p_sequence_length\"]]},\"id\":\"4552\",\"type\":\"HoverTool\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"1617\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1143\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1144\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1093\",\"type\":\"CDSView\"}},\"id\":\"1145\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2239\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2560\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3672\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"1618\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3671\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3672\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3615\",\"type\":\"CDSView\"}},\"id\":\"3673\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2240\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2561\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true]},\"id\":\"1595\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"3614\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2239\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2240\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2184\",\"type\":\"CDSView\"}},\"id\":\"2241\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1147\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2560\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2561\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2503\",\"type\":\"CDSView\"}},\"id\":\"2562\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3695\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3696\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3645\",\"type\":\"CDSView\"}},\"id\":\"3697\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1629\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1148\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2260\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3675\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1594\",\"type\":\"GroupFilter\"},{\"attributes\":{},\"id\":\"3351\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"data_source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1147\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1148\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1098\",\"type\":\"CDSView\"}},\"id\":\"1149\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2243\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2589\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2564\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3676\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"3352\",\"type\":\"Selection\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"3616\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3675\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3676\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3620\",\"type\":\"CDSView\"}},\"id\":\"3677\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2244\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1619\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2565\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"3644\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2243\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2244\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2189\",\"type\":\"CDSView\"}},\"id\":\"2245\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1151\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"3641\",\"type\":\"GroupFilter\"},{\"id\":\"3642\",\"type\":\"GroupFilter\"},{\"id\":\"3643\",\"type\":\"GroupFilter\"},{\"id\":\"3644\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"}},\"id\":\"3645\",\"type\":\"CDSView\"},{\"attributes\":{\"data_source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2564\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2565\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2508\",\"type\":\"CDSView\"}},\"id\":\"2566\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3696\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true]},\"id\":\"1620\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3219\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1152\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2259\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3679\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true]},\"id\":\"1625\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"3609\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"3647\",\"type\":\"GroupFilter\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"red\",\"white\",\"white\",\"white\",\"white\"],\"origin\":[\"Random\",\"Random\",\"Random\",\"Random\",\"Random\"],\"p_delay\":[\"None\",\"None\",\"None\",\"None\",1],\"p_sequence_length\":[1,2,3,4,1],\"runs\":[1,1,1,1,1],\"size\":[12.0,12.0,12.0,12.0,12.0],\"type\":[\"Final Incumbent\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\"],\"x\":{\"__ndarray__\":\"9XycTryI4z8V1Y/pH4nVP33uZXS0Jq8/nYRVUx7zyL/jng7jxhThPw==\",\"dtype\":\"float64\",\"shape\":[5]},\"y\":{\"__ndarray__\":\"mzBNdScfwr/cguHH3HPRv8eNZF3Badu/c7FyYAoG47/ygmwPQ8Sivw==\",\"dtype\":\"float64\",\"shape\":[5]},\"zorder\":[\"0\",\"0\",\"0\",\"0\",\"0\"]},\"selected\":{\"id\":\"1988\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1987\",\"type\":\"UnionRenderers\"}},\"id\":\"1004\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"data_source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1151\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1152\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1103\",\"type\":\"CDSView\"}},\"id\":\"1153\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2247\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"1617\",\"type\":\"GroupFilter\"},{\"id\":\"1618\",\"type\":\"GroupFilter\"},{\"id\":\"1619\",\"type\":\"GroupFilter\"},{\"id\":\"1620\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"}},\"id\":\"1621\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2568\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2588\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3680\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3679\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3680\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3625\",\"type\":\"CDSView\"}},\"id\":\"3681\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2248\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1624\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2569\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"3217\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"3641\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2247\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2248\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2194\",\"type\":\"CDSView\"}},\"id\":\"2249\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1155\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4201\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2568\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2569\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2513\",\"type\":\"CDSView\"}},\"id\":\"2570\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3695\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"1622\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"3639\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1156\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3683\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"1623\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3643\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"3622\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"2878\",\"type\":\"GroupFilter\"},{\"id\":\"2879\",\"type\":\"GroupFilter\"},{\"id\":\"2880\",\"type\":\"GroupFilter\"},{\"id\":\"2881\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"}},\"id\":\"2882\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4184\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"4110\",\"type\":\"GroupFilter\"},{\"id\":\"4111\",\"type\":\"GroupFilter\"},{\"id\":\"4112\",\"type\":\"GroupFilter\"},{\"id\":\"4113\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4114\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2251\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4185\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true]},\"id\":\"2881\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"4115\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2252\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4184\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4185\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4079\",\"type\":\"CDSView\"}},\"id\":\"4186\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2251\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2252\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2199\",\"type\":\"CDSView\"}},\"id\":\"2253\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"2884\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"4116\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4204\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4205\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4104\",\"type\":\"CDSView\"}},\"id\":\"4206\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2885\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"4117\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4188\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2501\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"2873\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2255\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"2883\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3623\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4189\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4118\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2256\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"4115\",\"type\":\"GroupFilter\"},{\"id\":\"4116\",\"type\":\"GroupFilter\"},{\"id\":\"4117\",\"type\":\"GroupFilter\"},{\"id\":\"4118\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4119\",\"type\":\"CDSView\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4188\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4189\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4084\",\"type\":\"CDSView\"}},\"id\":\"4190\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true]},\"id\":\"2886\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2255\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2256\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2204\",\"type\":\"CDSView\"}},\"id\":\"2257\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2880\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"4120\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2267\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"2879\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4205\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"4121\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2268\",\"type\":\"Scatter\"},{\"attributes\":{\"active\":[0],\"callback\":{\"id\":\"4556\",\"type\":\"CustomJS\"},\"labels\":[\"dqn seq del\"]},\"id\":\"4555\",\"type\":\"CheckboxButtonGroup\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"20\"},\"id\":\"4122\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2267\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2268\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2219\",\"type\":\"CDSView\"}},\"id\":\"2269\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"2883\",\"type\":\"GroupFilter\"},{\"id\":\"2884\",\"type\":\"GroupFilter\"},{\"id\":\"2885\",\"type\":\"GroupFilter\"},{\"id\":\"2886\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"}},\"id\":\"2887\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"3624\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4208\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4123\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true]},\"id\":\"2502\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2909\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4209\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"4120\",\"type\":\"GroupFilter\"},{\"id\":\"4121\",\"type\":\"GroupFilter\"},{\"id\":\"4122\",\"type\":\"GroupFilter\"},{\"id\":\"4123\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4124\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2271\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4208\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4209\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4109\",\"type\":\"CDSView\"}},\"id\":\"4210\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"4125\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2272\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2910\",\"type\":\"Scatter\"},{\"attributes\":{\"text\":\"Showing only configurations evaluated in:\"},\"id\":\"4557\",\"type\":\"Div\"},{\"attributes\":{\"data_source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2271\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2272\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2224\",\"type\":\"CDSView\"}},\"id\":\"2273\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"4126\",\"type\":\"GroupFilter\"},{\"attributes\":{\"args\":{\"checkbox\":{\"id\":\"4555\",\"type\":\"CheckboxButtonGroup\"},\"glyph0\":{\"id\":\"1117\",\"type\":\"GlyphRenderer\"},\"glyph1\":{\"id\":\"1121\",\"type\":\"GlyphRenderer\"},\"glyph10\":{\"id\":\"1157\",\"type\":\"GlyphRenderer\"},\"glyph100\":{\"id\":\"3685\",\"type\":\"GlyphRenderer\"},\"glyph101\":{\"id\":\"3689\",\"type\":\"GlyphRenderer\"},\"glyph102\":{\"id\":\"3693\",\"type\":\"GlyphRenderer\"},\"glyph103\":{\"id\":\"3697\",\"type\":\"GlyphRenderer\"},\"glyph104\":{\"id\":\"3701\",\"type\":\"GlyphRenderer\"},\"glyph105\":{\"id\":\"3705\",\"type\":\"GlyphRenderer\"},\"glyph106\":{\"id\":\"3709\",\"type\":\"GlyphRenderer\"},\"glyph107\":{\"id\":\"3713\",\"type\":\"GlyphRenderer\"},\"glyph108\":{\"id\":\"4138\",\"type\":\"GlyphRenderer\"},\"glyph109\":{\"id\":\"4142\",\"type\":\"GlyphRenderer\"},\"glyph11\":{\"id\":\"1161\",\"type\":\"GlyphRenderer\"},\"glyph110\":{\"id\":\"4146\",\"type\":\"GlyphRenderer\"},\"glyph111\":{\"id\":\"4150\",\"type\":\"GlyphRenderer\"},\"glyph112\":{\"id\":\"4154\",\"type\":\"GlyphRenderer\"},\"glyph113\":{\"id\":\"4158\",\"type\":\"GlyphRenderer\"},\"glyph114\":{\"id\":\"4162\",\"type\":\"GlyphRenderer\"},\"glyph115\":{\"id\":\"4166\",\"type\":\"GlyphRenderer\"},\"glyph116\":{\"id\":\"4170\",\"type\":\"GlyphRenderer\"},\"glyph117\":{\"id\":\"4174\",\"type\":\"GlyphRenderer\"},\"glyph118\":{\"id\":\"4178\",\"type\":\"GlyphRenderer\"},\"glyph119\":{\"id\":\"4182\",\"type\":\"GlyphRenderer\"},\"glyph12\":{\"id\":\"1366\",\"type\":\"GlyphRenderer\"},\"glyph120\":{\"id\":\"4186\",\"type\":\"GlyphRenderer\"},\"glyph121\":{\"id\":\"4190\",\"type\":\"GlyphRenderer\"},\"glyph122\":{\"id\":\"4194\",\"type\":\"GlyphRenderer\"},\"glyph123\":{\"id\":\"4198\",\"type\":\"GlyphRenderer\"},\"glyph124\":{\"id\":\"4202\",\"type\":\"GlyphRenderer\"},\"glyph125\":{\"id\":\"4206\",\"type\":\"GlyphRenderer\"},\"glyph126\":{\"id\":\"4210\",\"type\":\"GlyphRenderer\"},\"glyph127\":{\"id\":\"4214\",\"type\":\"GlyphRenderer\"},\"glyph128\":{\"id\":\"4218\",\"type\":\"GlyphRenderer\"},\"glyph129\":{\"id\":\"4222\",\"type\":\"GlyphRenderer\"},\"glyph13\":{\"id\":\"1370\",\"type\":\"GlyphRenderer\"},\"glyph130\":{\"id\":\"4226\",\"type\":\"GlyphRenderer\"},\"glyph131\":{\"id\":\"4230\",\"type\":\"GlyphRenderer\"},\"glyph14\":{\"id\":\"1374\",\"type\":\"GlyphRenderer\"},\"glyph15\":{\"id\":\"1378\",\"type\":\"GlyphRenderer\"},\"glyph16\":{\"id\":\"1382\",\"type\":\"GlyphRenderer\"},\"glyph17\":{\"id\":\"1386\",\"type\":\"GlyphRenderer\"},\"glyph18\":{\"id\":\"1390\",\"type\":\"GlyphRenderer\"},\"glyph19\":{\"id\":\"1394\",\"type\":\"GlyphRenderer\"},\"glyph2\":{\"id\":\"1125\",\"type\":\"GlyphRenderer\"},\"glyph20\":{\"id\":\"1398\",\"type\":\"GlyphRenderer\"},\"glyph21\":{\"id\":\"1402\",\"type\":\"GlyphRenderer\"},\"glyph22\":{\"id\":\"1406\",\"type\":\"GlyphRenderer\"},\"glyph23\":{\"id\":\"1410\",\"type\":\"GlyphRenderer\"},\"glyph24\":{\"id\":\"1635\",\"type\":\"GlyphRenderer\"},\"glyph25\":{\"id\":\"1639\",\"type\":\"GlyphRenderer\"},\"glyph26\":{\"id\":\"1643\",\"type\":\"GlyphRenderer\"},\"glyph27\":{\"id\":\"1647\",\"type\":\"GlyphRenderer\"},\"glyph28\":{\"id\":\"1651\",\"type\":\"GlyphRenderer\"},\"glyph29\":{\"id\":\"1655\",\"type\":\"GlyphRenderer\"},\"glyph3\":{\"id\":\"1129\",\"type\":\"GlyphRenderer\"},\"glyph30\":{\"id\":\"1659\",\"type\":\"GlyphRenderer\"},\"glyph31\":{\"id\":\"1663\",\"type\":\"GlyphRenderer\"},\"glyph32\":{\"id\":\"1667\",\"type\":\"GlyphRenderer\"},\"glyph33\":{\"id\":\"1671\",\"type\":\"GlyphRenderer\"},\"glyph34\":{\"id\":\"1675\",\"type\":\"GlyphRenderer\"},\"glyph35\":{\"id\":\"1679\",\"type\":\"GlyphRenderer\"},\"glyph36\":{\"id\":\"1924\",\"type\":\"GlyphRenderer\"},\"glyph37\":{\"id\":\"1928\",\"type\":\"GlyphRenderer\"},\"glyph38\":{\"id\":\"1932\",\"type\":\"GlyphRenderer\"},\"glyph39\":{\"id\":\"1936\",\"type\":\"GlyphRenderer\"},\"glyph4\":{\"id\":\"1133\",\"type\":\"GlyphRenderer\"},\"glyph40\":{\"id\":\"1940\",\"type\":\"GlyphRenderer\"},\"glyph41\":{\"id\":\"1944\",\"type\":\"GlyphRenderer\"},\"glyph42\":{\"id\":\"1948\",\"type\":\"GlyphRenderer\"},\"glyph43\":{\"id\":\"1952\",\"type\":\"GlyphRenderer\"},\"glyph44\":{\"id\":\"1956\",\"type\":\"GlyphRenderer\"},\"glyph45\":{\"id\":\"1960\",\"type\":\"GlyphRenderer\"},\"glyph46\":{\"id\":\"1964\",\"type\":\"GlyphRenderer\"},\"glyph47\":{\"id\":\"1968\",\"type\":\"GlyphRenderer\"},\"glyph48\":{\"id\":\"2233\",\"type\":\"GlyphRenderer\"},\"glyph49\":{\"id\":\"2237\",\"type\":\"GlyphRenderer\"},\"glyph5\":{\"id\":\"1137\",\"type\":\"GlyphRenderer\"},\"glyph50\":{\"id\":\"2241\",\"type\":\"GlyphRenderer\"},\"glyph51\":{\"id\":\"2245\",\"type\":\"GlyphRenderer\"},\"glyph52\":{\"id\":\"2249\",\"type\":\"GlyphRenderer\"},\"glyph53\":{\"id\":\"2253\",\"type\":\"GlyphRenderer\"},\"glyph54\":{\"id\":\"2257\",\"type\":\"GlyphRenderer\"},\"glyph55\":{\"id\":\"2261\",\"type\":\"GlyphRenderer\"},\"glyph56\":{\"id\":\"2265\",\"type\":\"GlyphRenderer\"},\"glyph57\":{\"id\":\"2269\",\"type\":\"GlyphRenderer\"},\"glyph58\":{\"id\":\"2273\",\"type\":\"GlyphRenderer\"},\"glyph59\":{\"id\":\"2277\",\"type\":\"GlyphRenderer\"},\"glyph6\":{\"id\":\"1141\",\"type\":\"GlyphRenderer\"},\"glyph60\":{\"id\":\"2562\",\"type\":\"GlyphRenderer\"},\"glyph61\":{\"id\":\"2566\",\"type\":\"GlyphRenderer\"},\"glyph62\":{\"id\":\"2570\",\"type\":\"GlyphRenderer\"},\"glyph63\":{\"id\":\"2574\",\"type\":\"GlyphRenderer\"},\"glyph64\":{\"id\":\"2578\",\"type\":\"GlyphRenderer\"},\"glyph65\":{\"id\":\"2582\",\"type\":\"GlyphRenderer\"},\"glyph66\":{\"id\":\"2586\",\"type\":\"GlyphRenderer\"},\"glyph67\":{\"id\":\"2590\",\"type\":\"GlyphRenderer\"},\"glyph68\":{\"id\":\"2594\",\"type\":\"GlyphRenderer\"},\"glyph69\":{\"id\":\"2598\",\"type\":\"GlyphRenderer\"},\"glyph7\":{\"id\":\"1145\",\"type\":\"GlyphRenderer\"},\"glyph70\":{\"id\":\"2602\",\"type\":\"GlyphRenderer\"},\"glyph71\":{\"id\":\"2606\",\"type\":\"GlyphRenderer\"},\"glyph72\":{\"id\":\"2911\",\"type\":\"GlyphRenderer\"},\"glyph73\":{\"id\":\"2915\",\"type\":\"GlyphRenderer\"},\"glyph74\":{\"id\":\"2919\",\"type\":\"GlyphRenderer\"},\"glyph75\":{\"id\":\"2923\",\"type\":\"GlyphRenderer\"},\"glyph76\":{\"id\":\"2927\",\"type\":\"GlyphRenderer\"},\"glyph77\":{\"id\":\"2931\",\"type\":\"GlyphRenderer\"},\"glyph78\":{\"id\":\"2935\",\"type\":\"GlyphRenderer\"},\"glyph79\":{\"id\":\"2939\",\"type\":\"GlyphRenderer\"},\"glyph8\":{\"id\":\"1149\",\"type\":\"GlyphRenderer\"},\"glyph80\":{\"id\":\"2943\",\"type\":\"GlyphRenderer\"},\"glyph81\":{\"id\":\"2947\",\"type\":\"GlyphRenderer\"},\"glyph82\":{\"id\":\"2951\",\"type\":\"GlyphRenderer\"},\"glyph83\":{\"id\":\"2955\",\"type\":\"GlyphRenderer\"},\"glyph84\":{\"id\":\"3280\",\"type\":\"GlyphRenderer\"},\"glyph85\":{\"id\":\"3284\",\"type\":\"GlyphRenderer\"},\"glyph86\":{\"id\":\"3288\",\"type\":\"GlyphRenderer\"},\"glyph87\":{\"id\":\"3292\",\"type\":\"GlyphRenderer\"},\"glyph88\":{\"id\":\"3296\",\"type\":\"GlyphRenderer\"},\"glyph89\":{\"id\":\"3300\",\"type\":\"GlyphRenderer\"},\"glyph9\":{\"id\":\"1153\",\"type\":\"GlyphRenderer\"},\"glyph90\":{\"id\":\"3304\",\"type\":\"GlyphRenderer\"},\"glyph91\":{\"id\":\"3308\",\"type\":\"GlyphRenderer\"},\"glyph92\":{\"id\":\"3312\",\"type\":\"GlyphRenderer\"},\"glyph93\":{\"id\":\"3316\",\"type\":\"GlyphRenderer\"},\"glyph94\":{\"id\":\"3320\",\"type\":\"GlyphRenderer\"},\"glyph95\":{\"id\":\"3324\",\"type\":\"GlyphRenderer\"},\"glyph96\":{\"id\":\"3669\",\"type\":\"GlyphRenderer\"},\"glyph97\":{\"id\":\"3673\",\"type\":\"GlyphRenderer\"},\"glyph98\":{\"id\":\"3677\",\"type\":\"GlyphRenderer\"},\"glyph99\":{\"id\":\"3681\",\"type\":\"GlyphRenderer\"},\"time_slider\":{\"id\":\"4554\",\"type\":\"Slider\"}},\"code\":\"checkbox.active = [];var glyphs = [glyph0, glyph1, glyph2, glyph3, glyph4, glyph5, glyph6, glyph7, glyph8, glyph9, glyph10, glyph11, glyph12, glyph13, glyph14, glyph15, glyph16, glyph17, glyph18, glyph19, glyph20, glyph21, glyph22, glyph23, glyph24, glyph25, glyph26, glyph27, glyph28, glyph29, glyph30, glyph31, glyph32, glyph33, glyph34, glyph35, glyph36, glyph37, glyph38, glyph39, glyph40, glyph41, glyph42, glyph43, glyph44, glyph45, glyph46, glyph47, glyph48, glyph49, glyph50, glyph51, glyph52, glyph53, glyph54, glyph55, glyph56, glyph57, glyph58, glyph59, glyph60, glyph61, glyph62, glyph63, glyph64, glyph65, glyph66, glyph67, glyph68, glyph69, glyph70, glyph71, glyph72, glyph73, glyph74, glyph75, glyph76, glyph77, glyph78, glyph79, glyph80, glyph81, glyph82, glyph83, glyph84, glyph85, glyph86, glyph87, glyph88, glyph89, glyph90, glyph91, glyph92, glyph93, glyph94, glyph95, glyph96, glyph97, glyph98, glyph99, glyph100, glyph101, glyph102, glyph103, glyph104, glyph105, glyph106, glyph107, glyph108, glyph109, glyph110, glyph111, glyph112, glyph113, glyph114, glyph115, glyph116, glyph117, glyph118, glyph119, glyph120, glyph121, glyph122, glyph123, glyph124, glyph125, glyph126, glyph127, glyph128, glyph129, glyph130, glyph131];var overtime = [[0,1,2,3,4,5,6,7,8,9,10,11],[12,13,14,15,16,17,18,19,20,21,22,23],[24,25,26,27,28,29,30,31,32,33,34,35],[36,37,38,39,40,41,42,43,44,45,46,47],[48,49,50,51,52,53,54,55,56,57,58,59],[60,61,62,63,64,65,66,67,68,69,70,71],[72,73,74,75,76,77,78,79,80,81,82,83],[84,85,86,87,88,89,90,91,92,93,94,95],[96,97,98,99,100,101,102,103,104,105,106,107],[108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131]];var runs = [[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131]];\\n glyphs.forEach(function(g) {\\n g.visible = false;\\n })\\n // union function\\n function union_arrays(x, y) {\\n var obj = {};\\n for (var i = x.length-1; i >= 0; -- i)\\n obj[x[i]] = x[i];\\n for (var i = y.length-1; i >= 0; -- i)\\n obj[y[i]] = y[i];\\n var res = []\\n for (var k in obj) {\\n if (obj.hasOwnProperty(k)) // <-- optional\\n res.push(obj[k]);\\n }\\n return res;\\n }\\n console.log(\\\"Timeslider: \\\" + time_slider.value);\\n console.log(\\\"Checkbox: \\\" + checkbox.active);var slider_labels = ['2.10', '3.20', '4.30', '5.40', '6.50', '7.60', '8.70', '10.90', '15.30', '21.90'];console.log(\\\"Detected slider_labels: \\\" + slider_labels);time_slider.title = \\\"Until wallclocktime \\\" + slider_labels[time_slider.value - 1] + \\\". Step no.\\\"; \\n var activate = [];\\n // if we want multiple checkboxes at the same time, we need to combine the arrays\\n checkbox.active.forEach(function(c) {\\n activate = union_arrays(activate, runs[c]);\\n })\\n // now the intersection of timeslider-activated and checkbox-activated\\n activate = activate.filter(value => -1 !== overtime[time_slider.value - 1].indexOf(value));\\n activate.forEach(function(idx) {\\n glyphs[idx].visible = true;\\n })\\n \"},\"id\":\"4560\",\"type\":\"CustomJS\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4212\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"2499\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2890\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"4127\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4213\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"2500\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"2894\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2275\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true]},\"id\":\"2891\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4128\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4212\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4213\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4114\",\"type\":\"CDSView\"}},\"id\":\"4214\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"2889\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2276\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"4125\",\"type\":\"GroupFilter\"},{\"id\":\"4126\",\"type\":\"GroupFilter\"},{\"id\":\"4127\",\"type\":\"GroupFilter\"},{\"id\":\"4128\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4129\",\"type\":\"CDSView\"},{\"attributes\":{\"data_source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2275\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2276\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2229\",\"type\":\"CDSView\"}},\"id\":\"2277\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"callback\":{\"id\":\"4560\",\"type\":\"CustomJS\"},\"icon\":null,\"label\":\"None\"},\"id\":\"4561\",\"type\":\"Button\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"4130\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4216\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"2888\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"2888\",\"type\":\"GroupFilter\"},{\"id\":\"2889\",\"type\":\"GroupFilter\"},{\"id\":\"2890\",\"type\":\"GroupFilter\"},{\"id\":\"2891\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"}},\"id\":\"2892\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4217\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"4131\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"3626\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4216\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4217\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4119\",\"type\":\"CDSView\"}},\"id\":\"4218\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"2893\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"20\"},\"id\":\"4132\",\"type\":\"GroupFilter\"},{\"attributes\":{\"args\":{\"checkbox\":{\"id\":\"4555\",\"type\":\"CheckboxButtonGroup\"},\"glyph0\":{\"id\":\"1117\",\"type\":\"GlyphRenderer\"},\"glyph1\":{\"id\":\"1121\",\"type\":\"GlyphRenderer\"},\"glyph10\":{\"id\":\"1157\",\"type\":\"GlyphRenderer\"},\"glyph100\":{\"id\":\"3685\",\"type\":\"GlyphRenderer\"},\"glyph101\":{\"id\":\"3689\",\"type\":\"GlyphRenderer\"},\"glyph102\":{\"id\":\"3693\",\"type\":\"GlyphRenderer\"},\"glyph103\":{\"id\":\"3697\",\"type\":\"GlyphRenderer\"},\"glyph104\":{\"id\":\"3701\",\"type\":\"GlyphRenderer\"},\"glyph105\":{\"id\":\"3705\",\"type\":\"GlyphRenderer\"},\"glyph106\":{\"id\":\"3709\",\"type\":\"GlyphRenderer\"},\"glyph107\":{\"id\":\"3713\",\"type\":\"GlyphRenderer\"},\"glyph108\":{\"id\":\"4138\",\"type\":\"GlyphRenderer\"},\"glyph109\":{\"id\":\"4142\",\"type\":\"GlyphRenderer\"},\"glyph11\":{\"id\":\"1161\",\"type\":\"GlyphRenderer\"},\"glyph110\":{\"id\":\"4146\",\"type\":\"GlyphRenderer\"},\"glyph111\":{\"id\":\"4150\",\"type\":\"GlyphRenderer\"},\"glyph112\":{\"id\":\"4154\",\"type\":\"GlyphRenderer\"},\"glyph113\":{\"id\":\"4158\",\"type\":\"GlyphRenderer\"},\"glyph114\":{\"id\":\"4162\",\"type\":\"GlyphRenderer\"},\"glyph115\":{\"id\":\"4166\",\"type\":\"GlyphRenderer\"},\"glyph116\":{\"id\":\"4170\",\"type\":\"GlyphRenderer\"},\"glyph117\":{\"id\":\"4174\",\"type\":\"GlyphRenderer\"},\"glyph118\":{\"id\":\"4178\",\"type\":\"GlyphRenderer\"},\"glyph119\":{\"id\":\"4182\",\"type\":\"GlyphRenderer\"},\"glyph12\":{\"id\":\"1366\",\"type\":\"GlyphRenderer\"},\"glyph120\":{\"id\":\"4186\",\"type\":\"GlyphRenderer\"},\"glyph121\":{\"id\":\"4190\",\"type\":\"GlyphRenderer\"},\"glyph122\":{\"id\":\"4194\",\"type\":\"GlyphRenderer\"},\"glyph123\":{\"id\":\"4198\",\"type\":\"GlyphRenderer\"},\"glyph124\":{\"id\":\"4202\",\"type\":\"GlyphRenderer\"},\"glyph125\":{\"id\":\"4206\",\"type\":\"GlyphRenderer\"},\"glyph126\":{\"id\":\"4210\",\"type\":\"GlyphRenderer\"},\"glyph127\":{\"id\":\"4214\",\"type\":\"GlyphRenderer\"},\"glyph128\":{\"id\":\"4218\",\"type\":\"GlyphRenderer\"},\"glyph129\":{\"id\":\"4222\",\"type\":\"GlyphRenderer\"},\"glyph13\":{\"id\":\"1370\",\"type\":\"GlyphRenderer\"},\"glyph130\":{\"id\":\"4226\",\"type\":\"GlyphRenderer\"},\"glyph131\":{\"id\":\"4230\",\"type\":\"GlyphRenderer\"},\"glyph14\":{\"id\":\"1374\",\"type\":\"GlyphRenderer\"},\"glyph15\":{\"id\":\"1378\",\"type\":\"GlyphRenderer\"},\"glyph16\":{\"id\":\"1382\",\"type\":\"GlyphRenderer\"},\"glyph17\":{\"id\":\"1386\",\"type\":\"GlyphRenderer\"},\"glyph18\":{\"id\":\"1390\",\"type\":\"GlyphRenderer\"},\"glyph19\":{\"id\":\"1394\",\"type\":\"GlyphRenderer\"},\"glyph2\":{\"id\":\"1125\",\"type\":\"GlyphRenderer\"},\"glyph20\":{\"id\":\"1398\",\"type\":\"GlyphRenderer\"},\"glyph21\":{\"id\":\"1402\",\"type\":\"GlyphRenderer\"},\"glyph22\":{\"id\":\"1406\",\"type\":\"GlyphRenderer\"},\"glyph23\":{\"id\":\"1410\",\"type\":\"GlyphRenderer\"},\"glyph24\":{\"id\":\"1635\",\"type\":\"GlyphRenderer\"},\"glyph25\":{\"id\":\"1639\",\"type\":\"GlyphRenderer\"},\"glyph26\":{\"id\":\"1643\",\"type\":\"GlyphRenderer\"},\"glyph27\":{\"id\":\"1647\",\"type\":\"GlyphRenderer\"},\"glyph28\":{\"id\":\"1651\",\"type\":\"GlyphRenderer\"},\"glyph29\":{\"id\":\"1655\",\"type\":\"GlyphRenderer\"},\"glyph3\":{\"id\":\"1129\",\"type\":\"GlyphRenderer\"},\"glyph30\":{\"id\":\"1659\",\"type\":\"GlyphRenderer\"},\"glyph31\":{\"id\":\"1663\",\"type\":\"GlyphRenderer\"},\"glyph32\":{\"id\":\"1667\",\"type\":\"GlyphRenderer\"},\"glyph33\":{\"id\":\"1671\",\"type\":\"GlyphRenderer\"},\"glyph34\":{\"id\":\"1675\",\"type\":\"GlyphRenderer\"},\"glyph35\":{\"id\":\"1679\",\"type\":\"GlyphRenderer\"},\"glyph36\":{\"id\":\"1924\",\"type\":\"GlyphRenderer\"},\"glyph37\":{\"id\":\"1928\",\"type\":\"GlyphRenderer\"},\"glyph38\":{\"id\":\"1932\",\"type\":\"GlyphRenderer\"},\"glyph39\":{\"id\":\"1936\",\"type\":\"GlyphRenderer\"},\"glyph4\":{\"id\":\"1133\",\"type\":\"GlyphRenderer\"},\"glyph40\":{\"id\":\"1940\",\"type\":\"GlyphRenderer\"},\"glyph41\":{\"id\":\"1944\",\"type\":\"GlyphRenderer\"},\"glyph42\":{\"id\":\"1948\",\"type\":\"GlyphRenderer\"},\"glyph43\":{\"id\":\"1952\",\"type\":\"GlyphRenderer\"},\"glyph44\":{\"id\":\"1956\",\"type\":\"GlyphRenderer\"},\"glyph45\":{\"id\":\"1960\",\"type\":\"GlyphRenderer\"},\"glyph46\":{\"id\":\"1964\",\"type\":\"GlyphRenderer\"},\"glyph47\":{\"id\":\"1968\",\"type\":\"GlyphRenderer\"},\"glyph48\":{\"id\":\"2233\",\"type\":\"GlyphRenderer\"},\"glyph49\":{\"id\":\"2237\",\"type\":\"GlyphRenderer\"},\"glyph5\":{\"id\":\"1137\",\"type\":\"GlyphRenderer\"},\"glyph50\":{\"id\":\"2241\",\"type\":\"GlyphRenderer\"},\"glyph51\":{\"id\":\"2245\",\"type\":\"GlyphRenderer\"},\"glyph52\":{\"id\":\"2249\",\"type\":\"GlyphRenderer\"},\"glyph53\":{\"id\":\"2253\",\"type\":\"GlyphRenderer\"},\"glyph54\":{\"id\":\"2257\",\"type\":\"GlyphRenderer\"},\"glyph55\":{\"id\":\"2261\",\"type\":\"GlyphRenderer\"},\"glyph56\":{\"id\":\"2265\",\"type\":\"GlyphRenderer\"},\"glyph57\":{\"id\":\"2269\",\"type\":\"GlyphRenderer\"},\"glyph58\":{\"id\":\"2273\",\"type\":\"GlyphRenderer\"},\"glyph59\":{\"id\":\"2277\",\"type\":\"GlyphRenderer\"},\"glyph6\":{\"id\":\"1141\",\"type\":\"GlyphRenderer\"},\"glyph60\":{\"id\":\"2562\",\"type\":\"GlyphRenderer\"},\"glyph61\":{\"id\":\"2566\",\"type\":\"GlyphRenderer\"},\"glyph62\":{\"id\":\"2570\",\"type\":\"GlyphRenderer\"},\"glyph63\":{\"id\":\"2574\",\"type\":\"GlyphRenderer\"},\"glyph64\":{\"id\":\"2578\",\"type\":\"GlyphRenderer\"},\"glyph65\":{\"id\":\"2582\",\"type\":\"GlyphRenderer\"},\"glyph66\":{\"id\":\"2586\",\"type\":\"GlyphRenderer\"},\"glyph67\":{\"id\":\"2590\",\"type\":\"GlyphRenderer\"},\"glyph68\":{\"id\":\"2594\",\"type\":\"GlyphRenderer\"},\"glyph69\":{\"id\":\"2598\",\"type\":\"GlyphRenderer\"},\"glyph7\":{\"id\":\"1145\",\"type\":\"GlyphRenderer\"},\"glyph70\":{\"id\":\"2602\",\"type\":\"GlyphRenderer\"},\"glyph71\":{\"id\":\"2606\",\"type\":\"GlyphRenderer\"},\"glyph72\":{\"id\":\"2911\",\"type\":\"GlyphRenderer\"},\"glyph73\":{\"id\":\"2915\",\"type\":\"GlyphRenderer\"},\"glyph74\":{\"id\":\"2919\",\"type\":\"GlyphRenderer\"},\"glyph75\":{\"id\":\"2923\",\"type\":\"GlyphRenderer\"},\"glyph76\":{\"id\":\"2927\",\"type\":\"GlyphRenderer\"},\"glyph77\":{\"id\":\"2931\",\"type\":\"GlyphRenderer\"},\"glyph78\":{\"id\":\"2935\",\"type\":\"GlyphRenderer\"},\"glyph79\":{\"id\":\"2939\",\"type\":\"GlyphRenderer\"},\"glyph8\":{\"id\":\"1149\",\"type\":\"GlyphRenderer\"},\"glyph80\":{\"id\":\"2943\",\"type\":\"GlyphRenderer\"},\"glyph81\":{\"id\":\"2947\",\"type\":\"GlyphRenderer\"},\"glyph82\":{\"id\":\"2951\",\"type\":\"GlyphRenderer\"},\"glyph83\":{\"id\":\"2955\",\"type\":\"GlyphRenderer\"},\"glyph84\":{\"id\":\"3280\",\"type\":\"GlyphRenderer\"},\"glyph85\":{\"id\":\"3284\",\"type\":\"GlyphRenderer\"},\"glyph86\":{\"id\":\"3288\",\"type\":\"GlyphRenderer\"},\"glyph87\":{\"id\":\"3292\",\"type\":\"GlyphRenderer\"},\"glyph88\":{\"id\":\"3296\",\"type\":\"GlyphRenderer\"},\"glyph89\":{\"id\":\"3300\",\"type\":\"GlyphRenderer\"},\"glyph9\":{\"id\":\"1153\",\"type\":\"GlyphRenderer\"},\"glyph90\":{\"id\":\"3304\",\"type\":\"GlyphRenderer\"},\"glyph91\":{\"id\":\"3308\",\"type\":\"GlyphRenderer\"},\"glyph92\":{\"id\":\"3312\",\"type\":\"GlyphRenderer\"},\"glyph93\":{\"id\":\"3316\",\"type\":\"GlyphRenderer\"},\"glyph94\":{\"id\":\"3320\",\"type\":\"GlyphRenderer\"},\"glyph95\":{\"id\":\"3324\",\"type\":\"GlyphRenderer\"},\"glyph96\":{\"id\":\"3669\",\"type\":\"GlyphRenderer\"},\"glyph97\":{\"id\":\"3673\",\"type\":\"GlyphRenderer\"},\"glyph98\":{\"id\":\"3677\",\"type\":\"GlyphRenderer\"},\"glyph99\":{\"id\":\"3681\",\"type\":\"GlyphRenderer\"},\"time_slider\":{\"id\":\"4554\",\"type\":\"Slider\"}},\"code\":\"var glyphs = [glyph0, glyph1, glyph2, glyph3, glyph4, glyph5, glyph6, glyph7, glyph8, glyph9, glyph10, glyph11, glyph12, glyph13, glyph14, glyph15, glyph16, glyph17, glyph18, glyph19, glyph20, glyph21, glyph22, glyph23, glyph24, glyph25, glyph26, glyph27, glyph28, glyph29, glyph30, glyph31, glyph32, glyph33, glyph34, glyph35, glyph36, glyph37, glyph38, glyph39, glyph40, glyph41, glyph42, glyph43, glyph44, glyph45, glyph46, glyph47, glyph48, glyph49, glyph50, glyph51, glyph52, glyph53, glyph54, glyph55, glyph56, glyph57, glyph58, glyph59, glyph60, glyph61, glyph62, glyph63, glyph64, glyph65, glyph66, glyph67, glyph68, glyph69, glyph70, glyph71, glyph72, glyph73, glyph74, glyph75, glyph76, glyph77, glyph78, glyph79, glyph80, glyph81, glyph82, glyph83, glyph84, glyph85, glyph86, glyph87, glyph88, glyph89, glyph90, glyph91, glyph92, glyph93, glyph94, glyph95, glyph96, glyph97, glyph98, glyph99, glyph100, glyph101, glyph102, glyph103, glyph104, glyph105, glyph106, glyph107, glyph108, glyph109, glyph110, glyph111, glyph112, glyph113, glyph114, glyph115, glyph116, glyph117, glyph118, glyph119, glyph120, glyph121, glyph122, glyph123, glyph124, glyph125, glyph126, glyph127, glyph128, glyph129, glyph130, glyph131];var overtime = [[0,1,2,3,4,5,6,7,8,9,10,11],[12,13,14,15,16,17,18,19,20,21,22,23],[24,25,26,27,28,29,30,31,32,33,34,35],[36,37,38,39,40,41,42,43,44,45,46,47],[48,49,50,51,52,53,54,55,56,57,58,59],[60,61,62,63,64,65,66,67,68,69,70,71],[72,73,74,75,76,77,78,79,80,81,82,83],[84,85,86,87,88,89,90,91,92,93,94,95],[96,97,98,99,100,101,102,103,104,105,106,107],[108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131]];var runs = [[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131]];\\n glyphs.forEach(function(g) {\\n g.visible = false;\\n })\\n // union function\\n function union_arrays(x, y) {\\n var obj = {};\\n for (var i = x.length-1; i >= 0; -- i)\\n obj[x[i]] = x[i];\\n for (var i = y.length-1; i >= 0; -- i)\\n obj[y[i]] = y[i];\\n var res = []\\n for (var k in obj) {\\n if (obj.hasOwnProperty(k)) // <-- optional\\n res.push(obj[k]);\\n }\\n return res;\\n }\\n console.log(\\\"Timeslider: \\\" + time_slider.value);\\n console.log(\\\"Checkbox: \\\" + checkbox.active);var slider_labels = ['2.10', '3.20', '4.30', '5.40', '6.50', '7.60', '8.70', '10.90', '15.30', '21.90'];console.log(\\\"Detected slider_labels: \\\" + slider_labels);time_slider.title = \\\"Until wallclocktime \\\" + slider_labels[time_slider.value - 1] + \\\". Step no.\\\"; \\n var activate = [];\\n // if we want multiple checkboxes at the same time, we need to combine the arrays\\n checkbox.active.forEach(function(c) {\\n activate = union_arrays(activate, runs[c]);\\n })\\n // now the intersection of timeslider-activated and checkbox-activated\\n activate = activate.filter(value => -1 !== overtime[time_slider.value - 1].indexOf(value));\\n activate.forEach(function(idx) {\\n glyphs[idx].visible = true;\\n })\\n \"},\"id\":\"4556\",\"type\":\"CustomJS\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4133\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true]},\"id\":\"2896\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4220\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"4130\",\"type\":\"GroupFilter\"},{\"id\":\"4131\",\"type\":\"GroupFilter\"},{\"id\":\"4132\",\"type\":\"GroupFilter\"},{\"id\":\"4133\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4134\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2895\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3633\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4221\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4136\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4220\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4221\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4124\",\"type\":\"CDSView\"}},\"id\":\"4222\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"red\",\"white\",\"white\",\"white\"],\"origin\":[\"Random\",\"Random\",\"Random\",\"Random\"],\"p_delay\":[\"None\",\"None\",\"None\",\"None\"],\"p_sequence_length\":[1,2,3,4],\"runs\":[1,1,1,1],\"size\":[12.0,12.0,12.0,12.0],\"type\":[\"Final Incumbent\",\"Candidate\",\"Candidate\",\"Candidate\"],\"x\":{\"__ndarray__\":\"9XycTryI4z8V1Y/pH4nVP33uZXS0Jq8/nYRVUx7zyL8=\",\"dtype\":\"float64\",\"shape\":[4]},\"y\":{\"__ndarray__\":\"mzBNdScfwr/cguHH3HPRv8eNZF3Badu/c7FyYAoG478=\",\"dtype\":\"float64\",\"shape\":[4]},\"zorder\":[\"0\",\"0\",\"0\",\"0\"]},\"selected\":{\"id\":\"1697\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1696\",\"type\":\"UnionRenderers\"}},\"id\":\"1003\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"filters\":[{\"id\":\"2848\",\"type\":\"GroupFilter\"},{\"id\":\"2849\",\"type\":\"GroupFilter\"},{\"id\":\"2850\",\"type\":\"GroupFilter\"},{\"id\":\"2851\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"}},\"id\":\"2852\",\"type\":\"CDSView\"},{\"attributes\":{\"filters\":[{\"id\":\"2893\",\"type\":\"GroupFilter\"},{\"id\":\"2894\",\"type\":\"GroupFilter\"},{\"id\":\"2895\",\"type\":\"GroupFilter\"},{\"id\":\"2896\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"}},\"id\":\"2897\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4137\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"2898\",\"type\":\"GroupFilter\"},{\"attributes\":{\"args\":{\"checkbox\":{\"id\":\"4555\",\"type\":\"CheckboxButtonGroup\"},\"glyph0\":{\"id\":\"1117\",\"type\":\"GlyphRenderer\"},\"glyph1\":{\"id\":\"1121\",\"type\":\"GlyphRenderer\"},\"glyph10\":{\"id\":\"1157\",\"type\":\"GlyphRenderer\"},\"glyph100\":{\"id\":\"3685\",\"type\":\"GlyphRenderer\"},\"glyph101\":{\"id\":\"3689\",\"type\":\"GlyphRenderer\"},\"glyph102\":{\"id\":\"3693\",\"type\":\"GlyphRenderer\"},\"glyph103\":{\"id\":\"3697\",\"type\":\"GlyphRenderer\"},\"glyph104\":{\"id\":\"3701\",\"type\":\"GlyphRenderer\"},\"glyph105\":{\"id\":\"3705\",\"type\":\"GlyphRenderer\"},\"glyph106\":{\"id\":\"3709\",\"type\":\"GlyphRenderer\"},\"glyph107\":{\"id\":\"3713\",\"type\":\"GlyphRenderer\"},\"glyph108\":{\"id\":\"4138\",\"type\":\"GlyphRenderer\"},\"glyph109\":{\"id\":\"4142\",\"type\":\"GlyphRenderer\"},\"glyph11\":{\"id\":\"1161\",\"type\":\"GlyphRenderer\"},\"glyph110\":{\"id\":\"4146\",\"type\":\"GlyphRenderer\"},\"glyph111\":{\"id\":\"4150\",\"type\":\"GlyphRenderer\"},\"glyph112\":{\"id\":\"4154\",\"type\":\"GlyphRenderer\"},\"glyph113\":{\"id\":\"4158\",\"type\":\"GlyphRenderer\"},\"glyph114\":{\"id\":\"4162\",\"type\":\"GlyphRenderer\"},\"glyph115\":{\"id\":\"4166\",\"type\":\"GlyphRenderer\"},\"glyph116\":{\"id\":\"4170\",\"type\":\"GlyphRenderer\"},\"glyph117\":{\"id\":\"4174\",\"type\":\"GlyphRenderer\"},\"glyph118\":{\"id\":\"4178\",\"type\":\"GlyphRenderer\"},\"glyph119\":{\"id\":\"4182\",\"type\":\"GlyphRenderer\"},\"glyph12\":{\"id\":\"1366\",\"type\":\"GlyphRenderer\"},\"glyph120\":{\"id\":\"4186\",\"type\":\"GlyphRenderer\"},\"glyph121\":{\"id\":\"4190\",\"type\":\"GlyphRenderer\"},\"glyph122\":{\"id\":\"4194\",\"type\":\"GlyphRenderer\"},\"glyph123\":{\"id\":\"4198\",\"type\":\"GlyphRenderer\"},\"glyph124\":{\"id\":\"4202\",\"type\":\"GlyphRenderer\"},\"glyph125\":{\"id\":\"4206\",\"type\":\"GlyphRenderer\"},\"glyph126\":{\"id\":\"4210\",\"type\":\"GlyphRenderer\"},\"glyph127\":{\"id\":\"4214\",\"type\":\"GlyphRenderer\"},\"glyph128\":{\"id\":\"4218\",\"type\":\"GlyphRenderer\"},\"glyph129\":{\"id\":\"4222\",\"type\":\"GlyphRenderer\"},\"glyph13\":{\"id\":\"1370\",\"type\":\"GlyphRenderer\"},\"glyph130\":{\"id\":\"4226\",\"type\":\"GlyphRenderer\"},\"glyph131\":{\"id\":\"4230\",\"type\":\"GlyphRenderer\"},\"glyph14\":{\"id\":\"1374\",\"type\":\"GlyphRenderer\"},\"glyph15\":{\"id\":\"1378\",\"type\":\"GlyphRenderer\"},\"glyph16\":{\"id\":\"1382\",\"type\":\"GlyphRenderer\"},\"glyph17\":{\"id\":\"1386\",\"type\":\"GlyphRenderer\"},\"glyph18\":{\"id\":\"1390\",\"type\":\"GlyphRenderer\"},\"glyph19\":{\"id\":\"1394\",\"type\":\"GlyphRenderer\"},\"glyph2\":{\"id\":\"1125\",\"type\":\"GlyphRenderer\"},\"glyph20\":{\"id\":\"1398\",\"type\":\"GlyphRenderer\"},\"glyph21\":{\"id\":\"1402\",\"type\":\"GlyphRenderer\"},\"glyph22\":{\"id\":\"1406\",\"type\":\"GlyphRenderer\"},\"glyph23\":{\"id\":\"1410\",\"type\":\"GlyphRenderer\"},\"glyph24\":{\"id\":\"1635\",\"type\":\"GlyphRenderer\"},\"glyph25\":{\"id\":\"1639\",\"type\":\"GlyphRenderer\"},\"glyph26\":{\"id\":\"1643\",\"type\":\"GlyphRenderer\"},\"glyph27\":{\"id\":\"1647\",\"type\":\"GlyphRenderer\"},\"glyph28\":{\"id\":\"1651\",\"type\":\"GlyphRenderer\"},\"glyph29\":{\"id\":\"1655\",\"type\":\"GlyphRenderer\"},\"glyph3\":{\"id\":\"1129\",\"type\":\"GlyphRenderer\"},\"glyph30\":{\"id\":\"1659\",\"type\":\"GlyphRenderer\"},\"glyph31\":{\"id\":\"1663\",\"type\":\"GlyphRenderer\"},\"glyph32\":{\"id\":\"1667\",\"type\":\"GlyphRenderer\"},\"glyph33\":{\"id\":\"1671\",\"type\":\"GlyphRenderer\"},\"glyph34\":{\"id\":\"1675\",\"type\":\"GlyphRenderer\"},\"glyph35\":{\"id\":\"1679\",\"type\":\"GlyphRenderer\"},\"glyph36\":{\"id\":\"1924\",\"type\":\"GlyphRenderer\"},\"glyph37\":{\"id\":\"1928\",\"type\":\"GlyphRenderer\"},\"glyph38\":{\"id\":\"1932\",\"type\":\"GlyphRenderer\"},\"glyph39\":{\"id\":\"1936\",\"type\":\"GlyphRenderer\"},\"glyph4\":{\"id\":\"1133\",\"type\":\"GlyphRenderer\"},\"glyph40\":{\"id\":\"1940\",\"type\":\"GlyphRenderer\"},\"glyph41\":{\"id\":\"1944\",\"type\":\"GlyphRenderer\"},\"glyph42\":{\"id\":\"1948\",\"type\":\"GlyphRenderer\"},\"glyph43\":{\"id\":\"1952\",\"type\":\"GlyphRenderer\"},\"glyph44\":{\"id\":\"1956\",\"type\":\"GlyphRenderer\"},\"glyph45\":{\"id\":\"1960\",\"type\":\"GlyphRenderer\"},\"glyph46\":{\"id\":\"1964\",\"type\":\"GlyphRenderer\"},\"glyph47\":{\"id\":\"1968\",\"type\":\"GlyphRenderer\"},\"glyph48\":{\"id\":\"2233\",\"type\":\"GlyphRenderer\"},\"glyph49\":{\"id\":\"2237\",\"type\":\"GlyphRenderer\"},\"glyph5\":{\"id\":\"1137\",\"type\":\"GlyphRenderer\"},\"glyph50\":{\"id\":\"2241\",\"type\":\"GlyphRenderer\"},\"glyph51\":{\"id\":\"2245\",\"type\":\"GlyphRenderer\"},\"glyph52\":{\"id\":\"2249\",\"type\":\"GlyphRenderer\"},\"glyph53\":{\"id\":\"2253\",\"type\":\"GlyphRenderer\"},\"glyph54\":{\"id\":\"2257\",\"type\":\"GlyphRenderer\"},\"glyph55\":{\"id\":\"2261\",\"type\":\"GlyphRenderer\"},\"glyph56\":{\"id\":\"2265\",\"type\":\"GlyphRenderer\"},\"glyph57\":{\"id\":\"2269\",\"type\":\"GlyphRenderer\"},\"glyph58\":{\"id\":\"2273\",\"type\":\"GlyphRenderer\"},\"glyph59\":{\"id\":\"2277\",\"type\":\"GlyphRenderer\"},\"glyph6\":{\"id\":\"1141\",\"type\":\"GlyphRenderer\"},\"glyph60\":{\"id\":\"2562\",\"type\":\"GlyphRenderer\"},\"glyph61\":{\"id\":\"2566\",\"type\":\"GlyphRenderer\"},\"glyph62\":{\"id\":\"2570\",\"type\":\"GlyphRenderer\"},\"glyph63\":{\"id\":\"2574\",\"type\":\"GlyphRenderer\"},\"glyph64\":{\"id\":\"2578\",\"type\":\"GlyphRenderer\"},\"glyph65\":{\"id\":\"2582\",\"type\":\"GlyphRenderer\"},\"glyph66\":{\"id\":\"2586\",\"type\":\"GlyphRenderer\"},\"glyph67\":{\"id\":\"2590\",\"type\":\"GlyphRenderer\"},\"glyph68\":{\"id\":\"2594\",\"type\":\"GlyphRenderer\"},\"glyph69\":{\"id\":\"2598\",\"type\":\"GlyphRenderer\"},\"glyph7\":{\"id\":\"1145\",\"type\":\"GlyphRenderer\"},\"glyph70\":{\"id\":\"2602\",\"type\":\"GlyphRenderer\"},\"glyph71\":{\"id\":\"2606\",\"type\":\"GlyphRenderer\"},\"glyph72\":{\"id\":\"2911\",\"type\":\"GlyphRenderer\"},\"glyph73\":{\"id\":\"2915\",\"type\":\"GlyphRenderer\"},\"glyph74\":{\"id\":\"2919\",\"type\":\"GlyphRenderer\"},\"glyph75\":{\"id\":\"2923\",\"type\":\"GlyphRenderer\"},\"glyph76\":{\"id\":\"2927\",\"type\":\"GlyphRenderer\"},\"glyph77\":{\"id\":\"2931\",\"type\":\"GlyphRenderer\"},\"glyph78\":{\"id\":\"2935\",\"type\":\"GlyphRenderer\"},\"glyph79\":{\"id\":\"2939\",\"type\":\"GlyphRenderer\"},\"glyph8\":{\"id\":\"1149\",\"type\":\"GlyphRenderer\"},\"glyph80\":{\"id\":\"2943\",\"type\":\"GlyphRenderer\"},\"glyph81\":{\"id\":\"2947\",\"type\":\"GlyphRenderer\"},\"glyph82\":{\"id\":\"2951\",\"type\":\"GlyphRenderer\"},\"glyph83\":{\"id\":\"2955\",\"type\":\"GlyphRenderer\"},\"glyph84\":{\"id\":\"3280\",\"type\":\"GlyphRenderer\"},\"glyph85\":{\"id\":\"3284\",\"type\":\"GlyphRenderer\"},\"glyph86\":{\"id\":\"3288\",\"type\":\"GlyphRenderer\"},\"glyph87\":{\"id\":\"3292\",\"type\":\"GlyphRenderer\"},\"glyph88\":{\"id\":\"3296\",\"type\":\"GlyphRenderer\"},\"glyph89\":{\"id\":\"3300\",\"type\":\"GlyphRenderer\"},\"glyph9\":{\"id\":\"1153\",\"type\":\"GlyphRenderer\"},\"glyph90\":{\"id\":\"3304\",\"type\":\"GlyphRenderer\"},\"glyph91\":{\"id\":\"3308\",\"type\":\"GlyphRenderer\"},\"glyph92\":{\"id\":\"3312\",\"type\":\"GlyphRenderer\"},\"glyph93\":{\"id\":\"3316\",\"type\":\"GlyphRenderer\"},\"glyph94\":{\"id\":\"3320\",\"type\":\"GlyphRenderer\"},\"glyph95\":{\"id\":\"3324\",\"type\":\"GlyphRenderer\"},\"glyph96\":{\"id\":\"3669\",\"type\":\"GlyphRenderer\"},\"glyph97\":{\"id\":\"3673\",\"type\":\"GlyphRenderer\"},\"glyph98\":{\"id\":\"3677\",\"type\":\"GlyphRenderer\"},\"glyph99\":{\"id\":\"3681\",\"type\":\"GlyphRenderer\"},\"time_slider\":{\"id\":\"4554\",\"type\":\"Slider\"}},\"code\":\"checkbox.active = [0];var glyphs = [glyph0, glyph1, glyph2, glyph3, glyph4, glyph5, glyph6, glyph7, glyph8, glyph9, glyph10, glyph11, glyph12, glyph13, glyph14, glyph15, glyph16, glyph17, glyph18, glyph19, glyph20, glyph21, glyph22, glyph23, glyph24, glyph25, glyph26, glyph27, glyph28, glyph29, glyph30, glyph31, glyph32, glyph33, glyph34, glyph35, glyph36, glyph37, glyph38, glyph39, glyph40, glyph41, glyph42, glyph43, glyph44, glyph45, glyph46, glyph47, glyph48, glyph49, glyph50, glyph51, glyph52, glyph53, glyph54, glyph55, glyph56, glyph57, glyph58, glyph59, glyph60, glyph61, glyph62, glyph63, glyph64, glyph65, glyph66, glyph67, glyph68, glyph69, glyph70, glyph71, glyph72, glyph73, glyph74, glyph75, glyph76, glyph77, glyph78, glyph79, glyph80, glyph81, glyph82, glyph83, glyph84, glyph85, glyph86, glyph87, glyph88, glyph89, glyph90, glyph91, glyph92, glyph93, glyph94, glyph95, glyph96, glyph97, glyph98, glyph99, glyph100, glyph101, glyph102, glyph103, glyph104, glyph105, glyph106, glyph107, glyph108, glyph109, glyph110, glyph111, glyph112, glyph113, glyph114, glyph115, glyph116, glyph117, glyph118, glyph119, glyph120, glyph121, glyph122, glyph123, glyph124, glyph125, glyph126, glyph127, glyph128, glyph129, glyph130, glyph131];var overtime = [[0,1,2,3,4,5,6,7,8,9,10,11],[12,13,14,15,16,17,18,19,20,21,22,23],[24,25,26,27,28,29,30,31,32,33,34,35],[36,37,38,39,40,41,42,43,44,45,46,47],[48,49,50,51,52,53,54,55,56,57,58,59],[60,61,62,63,64,65,66,67,68,69,70,71],[72,73,74,75,76,77,78,79,80,81,82,83],[84,85,86,87,88,89,90,91,92,93,94,95],[96,97,98,99,100,101,102,103,104,105,106,107],[108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131]];var runs = [[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131]];\\n glyphs.forEach(function(g) {\\n g.visible = false;\\n })\\n // union function\\n function union_arrays(x, y) {\\n var obj = {};\\n for (var i = x.length-1; i >= 0; -- i)\\n obj[x[i]] = x[i];\\n for (var i = y.length-1; i >= 0; -- i)\\n obj[y[i]] = y[i];\\n var res = []\\n for (var k in obj) {\\n if (obj.hasOwnProperty(k)) // <-- optional\\n res.push(obj[k]);\\n }\\n return res;\\n }\\n console.log(\\\"Timeslider: \\\" + time_slider.value);\\n console.log(\\\"Checkbox: \\\" + checkbox.active);var slider_labels = ['2.10', '3.20', '4.30', '5.40', '6.50', '7.60', '8.70', '10.90', '15.30', '21.90'];console.log(\\\"Detected slider_labels: \\\" + slider_labels);time_slider.title = \\\"Until wallclocktime \\\" + slider_labels[time_slider.value - 1] + \\\". Step no.\\\"; \\n var activate = [];\\n // if we want multiple checkboxes at the same time, we need to combine the arrays\\n checkbox.active.forEach(function(c) {\\n activate = union_arrays(activate, runs[c]);\\n })\\n // now the intersection of timeslider-activated and checkbox-activated\\n activate = activate.filter(value => -1 !== overtime[time_slider.value - 1].indexOf(value));\\n activate.forEach(function(idx) {\\n glyphs[idx].visible = true;\\n })\\n \"},\"id\":\"4558\",\"type\":\"CustomJS\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4136\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4137\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4019\",\"type\":\"CDSView\"}},\"id\":\"4138\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4224\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4225\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"2899\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4204\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4224\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4225\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4129\",\"type\":\"CDSView\"}},\"id\":\"4226\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4140\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2900\",\"type\":\"GroupFilter\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"red\",\"white\"],\"origin\":[\"Random\",\"Random\"],\"p_delay\":[\"None\",\"None\"],\"p_sequence_length\":[1,2],\"runs\":[1,1],\"size\":[12.0,12.0],\"type\":[\"Final Incumbent\",\"Candidate\"],\"x\":{\"__ndarray__\":\"9XycTryI4z8V1Y/pH4nVPw==\",\"dtype\":\"float64\",\"shape\":[2]},\"y\":{\"__ndarray__\":\"mzBNdScfwr/cguHH3HPRvw==\",\"dtype\":\"float64\",\"shape\":[2]},\"zorder\":[\"0\",\"0\"]},\"selected\":{\"id\":\"1175\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1174\",\"type\":\"UnionRenderers\"}},\"id\":\"1001\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4141\",\"type\":\"Scatter\"},{\"attributes\":{\"callback\":{\"id\":\"4558\",\"type\":\"CustomJS\"},\"icon\":null,\"label\":\"All\"},\"id\":\"4559\",\"type\":\"Button\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true]},\"id\":\"2901\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4140\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4141\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4024\",\"type\":\"CDSView\"}},\"id\":\"4142\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"2898\",\"type\":\"GroupFilter\"},{\"id\":\"2899\",\"type\":\"GroupFilter\"},{\"id\":\"2900\",\"type\":\"GroupFilter\"},{\"id\":\"2901\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"}},\"id\":\"2902\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4228\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4229\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"2903\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4228\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4229\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4134\",\"type\":\"CDSView\"}},\"id\":\"4230\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4144\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"2499\",\"type\":\"GroupFilter\"},{\"id\":\"2500\",\"type\":\"GroupFilter\"},{\"id\":\"2501\",\"type\":\"GroupFilter\"},{\"id\":\"2502\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"}},\"id\":\"2503\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"2904\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4145\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"2298\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2905\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4144\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4145\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4029\",\"type\":\"CDSView\"}},\"id\":\"4146\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"2299\",\"type\":\"Selection\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true]},\"id\":\"2906\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4200\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4201\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4099\",\"type\":\"CDSView\"}},\"id\":\"4202\",\"type\":\"GlyphRenderer\"}],\"root_ids\":[\"4575\"]},\"title\":\"Bokeh Application\",\"version\":\"1.1.0\"}};\n", + " var render_items = [{\"docid\":\"06bbb144-6c77-4643-bce0-9a725c3d0ad9\",\"roots\":{\"4575\":\"c1c87f82-af72-4478-b825-77e6d526594c\"}}];\n", + " root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", + "\n", + " }\n", + " if (root.Bokeh !== undefined) {\n", + " embed_document(root);\n", + " } else {\n", + " var attempts = 0;\n", + " var timer = setInterval(function(root) {\n", + " if (root.Bokeh !== undefined) {\n", + " embed_document(root);\n", + " clearInterval(timer);\n", + " }\n", + " attempts++;\n", + " if (attempts > 100) {\n", + " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n", + " clearInterval(timer);\n", + " }\n", + " }, 10, root)\n", + " }\n", + "})(window);" + ], + "application/vnd.bokehjs_exec.v0+json": "" + }, + "metadata": { + "application/vnd.bokehjs_exec.v0+json": { + "id": "4575" + } + }, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cave.configurator_footprint()" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "#won't show \n", + "cave.feature_importance()" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "cave.algorithm_footprints()" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
\n", + " \n", + " Loading BokehJS ...\n", + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "\n", + "(function(root) {\n", + " function now() {\n", + " return new Date();\n", + " }\n", + "\n", + " var force = true;\n", + "\n", + " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", + " root._bokeh_onload_callbacks = [];\n", + " root._bokeh_is_loading = undefined;\n", + " }\n", + "\n", + " var JS_MIME_TYPE = 'application/javascript';\n", + " var HTML_MIME_TYPE = 'text/html';\n", + " var EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n", + " var CLASS_NAME = 'output_bokeh rendered_html';\n", + "\n", + " /**\n", + " * Render data to the DOM node\n", + " */\n", + " function render(props, node) {\n", + " var script = document.createElement(\"script\");\n", + " node.appendChild(script);\n", + " }\n", + "\n", + " /**\n", + " * Handle when an output is cleared or removed\n", + " */\n", + " function handleClearOutput(event, handle) {\n", + " var cell = handle.cell;\n", + "\n", + " var id = cell.output_area._bokeh_element_id;\n", + " var server_id = cell.output_area._bokeh_server_id;\n", + " // Clean up Bokeh references\n", + " if (id != null && id in Bokeh.index) {\n", + " Bokeh.index[id].model.document.clear();\n", + " delete Bokeh.index[id];\n", + " }\n", + "\n", + " if (server_id !== undefined) {\n", + " // Clean up Bokeh references\n", + " var cmd = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n", + " cell.notebook.kernel.execute(cmd, {\n", + " iopub: {\n", + " output: function(msg) {\n", + " var id = msg.content.text.trim();\n", + " if (id in Bokeh.index) {\n", + " Bokeh.index[id].model.document.clear();\n", + " delete Bokeh.index[id];\n", + " }\n", + " }\n", + " }\n", + " });\n", + " // Destroy server and session\n", + " var cmd = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n", + " cell.notebook.kernel.execute(cmd);\n", + " }\n", + " }\n", + "\n", + " /**\n", + " * Handle when a new output is added\n", + " */\n", + " function handleAddOutput(event, handle) {\n", + " var output_area = handle.output_area;\n", + " var output = handle.output;\n", + "\n", + " // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n", + " if ((output.output_type != \"display_data\") || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", + " return\n", + " }\n", + "\n", + " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", + "\n", + " if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n", + " toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n", + " // store reference to embed id on output_area\n", + " output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", + " }\n", + " if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", + " var bk_div = document.createElement(\"div\");\n", + " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", + " var script_attrs = bk_div.children[0].attributes;\n", + " for (var i = 0; i < script_attrs.length; i++) {\n", + " toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n", + " }\n", + " // store reference to server id on output_area\n", + " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", + " }\n", + " }\n", + "\n", + " function register_renderer(events, OutputArea) {\n", + "\n", + " function append_mime(data, metadata, element) {\n", + " // create a DOM node to render to\n", + " var toinsert = this.create_output_subarea(\n", + " metadata,\n", + " CLASS_NAME,\n", + " EXEC_MIME_TYPE\n", + " );\n", + " this.keyboard_manager.register_events(toinsert);\n", + " // Render to node\n", + " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", + " render(props, toinsert[toinsert.length - 1]);\n", + " element.append(toinsert);\n", + " return toinsert\n", + " }\n", + "\n", + " /* Handle when an output is cleared or removed */\n", + " events.on('clear_output.CodeCell', handleClearOutput);\n", + " events.on('delete.Cell', handleClearOutput);\n", + "\n", + " /* Handle when a new output is added */\n", + " events.on('output_added.OutputArea', handleAddOutput);\n", + "\n", + " /**\n", + " * Register the mime type and append_mime function with output_area\n", + " */\n", + " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", + " /* Is output safe? */\n", + " safe: true,\n", + " /* Index of renderer in `output_area.display_order` */\n", + " index: 0\n", + " });\n", + " }\n", + "\n", + " // register the mime type if in Jupyter Notebook environment and previously unregistered\n", + " if (root.Jupyter !== undefined) {\n", + " var events = require('base/js/events');\n", + " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", + "\n", + " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", + " register_renderer(events, OutputArea);\n", + " }\n", + " }\n", + "\n", + " \n", + " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", + " root._bokeh_timeout = Date.now() + 5000;\n", + " root._bokeh_failed_load = false;\n", + " }\n", + "\n", + " var NB_LOAD_WARNING = {'data': {'text/html':\n", + " \"
\\n\"+\n", + " \"

\\n\"+\n", + " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", + " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", + " \"

\\n\"+\n", + " \"
    \\n\"+\n", + " \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n", + " \"
  • use INLINE resources instead, as so:
  • \\n\"+\n", + " \"
\\n\"+\n", + " \"\\n\"+\n", + " \"from bokeh.resources import INLINE\\n\"+\n", + " \"output_notebook(resources=INLINE)\\n\"+\n", + " \"\\n\"+\n", + " \"
\"}};\n", + "\n", + " function display_loaded() {\n", + " var el = document.getElementById(\"5122\");\n", + " if (el != null) {\n", + " el.textContent = \"BokehJS is loading...\";\n", + " }\n", + " if (root.Bokeh !== undefined) {\n", + " if (el != null) {\n", + " el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n", + " }\n", + " } else if (Date.now() < root._bokeh_timeout) {\n", + " setTimeout(display_loaded, 100)\n", + " }\n", + " }\n", + "\n", + "\n", + " function run_callbacks() {\n", + " try {\n", + " root._bokeh_onload_callbacks.forEach(function(callback) {\n", + " if (callback != null)\n", + " callback();\n", + " });\n", + " } finally {\n", + " delete root._bokeh_onload_callbacks\n", + " }\n", + " console.debug(\"Bokeh: all callbacks have finished\");\n", + " }\n", + "\n", + " function load_libs(css_urls, js_urls, callback) {\n", + " if (css_urls == null) css_urls = [];\n", + " if (js_urls == null) js_urls = [];\n", + "\n", + " root._bokeh_onload_callbacks.push(callback);\n", + " if (root._bokeh_is_loading > 0) {\n", + " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", + " return null;\n", + " }\n", + " if (js_urls == null || js_urls.length === 0) {\n", + " run_callbacks();\n", + " return null;\n", + " }\n", + " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", + " root._bokeh_is_loading = css_urls.length + js_urls.length;\n", + "\n", + " function on_load() {\n", + " root._bokeh_is_loading--;\n", + " if (root._bokeh_is_loading === 0) {\n", + " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", + " run_callbacks()\n", + " }\n", + " }\n", + "\n", + " function on_error() {\n", + " console.error(\"failed to load \" + url);\n", + " }\n", + "\n", + " for (var i = 0; i < css_urls.length; i++) {\n", + " var url = css_urls[i];\n", + " const element = document.createElement(\"link\");\n", + " element.onload = on_load;\n", + " element.onerror = on_error;\n", + " element.rel = \"stylesheet\";\n", + " element.type = \"text/css\";\n", + " element.href = url;\n", + " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", + " document.body.appendChild(element);\n", + " }\n", + "\n", + " for (var i = 0; i < js_urls.length; i++) {\n", + " var url = js_urls[i];\n", + " var element = document.createElement('script');\n", + " element.onload = on_load;\n", + " element.onerror = on_error;\n", + " element.async = false;\n", + " element.src = url;\n", + " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", + " document.head.appendChild(element);\n", + " }\n", + " };var element = document.getElementById(\"5122\");\n", + " if (element == null) {\n", + " console.error(\"Bokeh: ERROR: autoload.js configured with elementid '5122' but no matching script tag was found. \")\n", + " return false;\n", + " }\n", + "\n", + " function inject_raw_css(css) {\n", + " const element = document.createElement(\"style\");\n", + " element.appendChild(document.createTextNode(css));\n", + " document.body.appendChild(element);\n", + " }\n", + "\n", + " var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.1.0.min.js\"];\n", + " var css_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.css\"];\n", + "\n", + " var inline_js = [\n", + " function(Bokeh) {\n", + " Bokeh.set_log_level(\"info\");\n", + " },\n", + " \n", + " function(Bokeh) {\n", + " (function(root, factory) {\n", + " // if(typeof exports === 'object' && typeof module === 'object')\n", + " // factory(require(\"Bokeh\"));\n", + " // else if(typeof define === 'function' && define.amd)\n", + " // define([\"Bokeh\"], factory);\n", + " // else if(typeof exports === 'object')\n", + " // factory(require(\"Bokeh\"));\n", + " // else\n", + " factory(root[\"Bokeh\"]);\n", + " })(this, function(Bokeh) {\n", + " var define;\n", + " return (function outer(modules, entry) {\n", + " if (Bokeh != null) {\n", + " return Bokeh.register_plugin(modules, {}, entry);\n", + " } else {\n", + " throw new Error(\"Cannot find Bokeh. You have to load it prior to loading plugins.\");\n", + " }\n", + " })\n", + " ({\n", + " \"custom/main\": function(require, module, exports) {\n", + " var models = {\n", + " \"ParallelResetTool\": require(\"custom/cave.plot.parallel_plot.parallel_reset.parallel_reset_tool\").ParallelResetTool,\n", + " \"ParallelSelectionTool\": require(\"custom/cave.plot.parallel_plot.parallel_selection_tool.parallel_selection_tool\").ParallelSelectionTool\n", + " };\n", + " require(\"base\").register_models(models);\n", + " module.exports = models;\n", + " },\n", + " \"custom/cave.plot.parallel_plot.parallel_reset.parallel_reset_tool\": function(require, module, exports) {\n", + " \"use strict\";\n", + " var __extends = (this && this.__extends) || (function () {\n", + " var extendStatics = function (d, b) {\n", + " extendStatics = Object.setPrototypeOf ||\n", + " ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n", + " function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n", + " return extendStatics(d, b);\n", + " };\n", + " return function (d, b) {\n", + " extendStatics(d, b);\n", + " function __() { this.constructor = d; }\n", + " d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n", + " };\n", + " })();\n", + " Object.defineProperty(exports, \"__esModule\", { value: true });\n", + " var action_tool_1 = require(\"models/tools/actions/action_tool\");\n", + " var ParallelResetToolView = /** @class */ (function (_super) {\n", + " __extends(ParallelResetToolView, _super);\n", + " function ParallelResetToolView() {\n", + " return _super !== null && _super.apply(this, arguments) || this;\n", + " }\n", + " ParallelResetToolView.prototype.doit = function () {\n", + " this.plot_view.reset_range();\n", + " };\n", + " return ParallelResetToolView;\n", + " }(action_tool_1.ActionToolView));\n", + " exports.ParallelResetToolView = ParallelResetToolView;\n", + " var ParallelResetTool = /** @class */ (function (_super) {\n", + " __extends(ParallelResetTool, _super);\n", + " function ParallelResetTool(attrs) {\n", + " var _this = _super.call(this, attrs) || this;\n", + " _this.tool_name = \"Reset Zoom\";\n", + " _this.icon = \"bk-tool-icon-reset\";\n", + " return _this;\n", + " }\n", + " ParallelResetTool.initClass = function () {\n", + " this.prototype.type = \"ParallelResetTool\";\n", + " this.prototype.default_view = ParallelResetToolView;\n", + " };\n", + " return ParallelResetTool;\n", + " }(action_tool_1.ActionTool));\n", + " exports.ParallelResetTool = ParallelResetTool;\n", + " ParallelResetTool.initClass();\n", + "\n", + " },\n", + " \"custom/cave.plot.parallel_plot.parallel_selection_tool.parallel_selection_tool\": function(require, module, exports) {\n", + " \"use strict\";\n", + " var __extends = (this && this.__extends) || (function () {\n", + " var extendStatics = function (d, b) {\n", + " extendStatics = Object.setPrototypeOf ||\n", + " ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n", + " function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n", + " return extendStatics(d, b);\n", + " };\n", + " return function (d, b) {\n", + " extendStatics(d, b);\n", + " function __() { this.constructor = d; }\n", + " d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n", + " };\n", + " })();\n", + " Object.defineProperty(exports, \"__esModule\", { value: true });\n", + " var p = require(\"core/properties\");\n", + " var box_select_tool_1 = require(\"models/tools/gestures/box_select_tool\");\n", + " var array_1 = require(\"core/util/array\");\n", + " var dom_1 = require(\"core/dom\");\n", + " function find_indices_in(array, _a) {\n", + " var inf = _a[0], sup = _a[1];\n", + " return array.reduce(function (prev, curr, index) {\n", + " return (inf <= curr && curr <= sup) ? prev.concat(index) : prev;\n", + " }, []);\n", + " }\n", + " function index_array(array, indices) {\n", + " return indices.reduce(function (a, i) { return a.concat(array[i]); }, []);\n", + " }\n", + " function combineByKey(key, array) {\n", + " var keys = Object.keys(array[0]);\n", + " var combined = [];\n", + " array.forEach(function (itm) {\n", + " var idx = combined.map(function (item) { return item[key]; }).indexOf(itm[key]);\n", + " if (idx >= 0) {\n", + " keys.forEach(function (element) {\n", + " if (element != key)\n", + " combined[idx][element].push(itm[element]);\n", + " });\n", + " }\n", + " else {\n", + " var new_object_1 = {};\n", + " keys.forEach(function (element) {\n", + " if (element == key) {\n", + " new_object_1[element] = itm[element];\n", + " }\n", + " else {\n", + " new_object_1[element] = [itm[element]];\n", + " }\n", + " });\n", + " combined.push(new_object_1);\n", + " }\n", + " });\n", + " return combined;\n", + " }\n", + " var ParallelSelectionView = /** @class */ (function (_super) {\n", + " __extends(ParallelSelectionView, _super);\n", + " function ParallelSelectionView() {\n", + " var _this = _super !== null && _super.apply(this, arguments) || this;\n", + " _this.selection_mode = \"add\";\n", + " _this.panning = false;\n", + " return _this;\n", + " }\n", + " ParallelSelectionView.prototype.initialize = function () {\n", + " var _this = this;\n", + " _super.prototype.initialize.call(this);\n", + " var frame = this.plot_view.frame;\n", + " var _a = this.model.renderer_select, x_range_name_select = _a.x_range_name, y_range_name_select = _a.y_range_name;\n", + " var _b = this.model.renderer_data, x_range_name_data = _b.x_range_name, y_range_name_data = _b.y_range_name;\n", + " if (x_range_name_select == x_range_name_data && y_range_name_select == y_range_name_data) {\n", + " this.xscale = frame.xscales[x_range_name_select];\n", + " this.yscale = frame.yscales[y_range_name_select];\n", + " }\n", + " else\n", + " throw new Error(\"selection and data does not share the same ranges\");\n", + " //TODO test if parallel CDS is valid (xs for each line should be identical)\n", + " this.glyph_select = this.model.renderer_select.glyph;\n", + " this.glyph_data = this.model.renderer_data.glyph;\n", + " this.cds_select = this.model.renderer_select.data_source;\n", + " this.cds_data = this.model.renderer_data.data_source;\n", + " var _c = [this.glyph_data.xs.field, this.glyph_data.ys.field], xskey = _c[0], yskey = _c[1];\n", + " this.xdata = this.cds_data.get_array(xskey)[0];\n", + " this.ydataT = array_1.transpose(this.cds_data.get_array(yskey));\n", + " this.selection_indices = [];\n", + " this.connect(this.plot_view.frame.x_ranges[this.model.renderer_select.x_range_name].change, function () { return _this._resize_boxes_on_zoom(); });\n", + " this.connect(this.cds_select.change, function () { return _this._update_data_selection(); });\n", + " };\n", + " Object.defineProperty(ParallelSelectionView.prototype, \"_box_width\", {\n", + " get: function () {\n", + " return this.xscale.invert(this.model.box_width) - this.xscale.invert(0);\n", + " },\n", + " enumerable: true,\n", + " configurable: true\n", + " });\n", + " Object.defineProperty(ParallelSelectionView.prototype, \"_cds_select_keys\", {\n", + " get: function () {\n", + " var glyph_select = this.glyph_select;\n", + " var _a = [glyph_select.x.field, glyph_select.y.field], xkey = _a[0], ykey = _a[1];\n", + " var _b = [glyph_select.width.field, glyph_select.height.field], wkey = _b[0], hkey = _b[1];\n", + " return { xkey: xkey, ykey: ykey, wkey: wkey, hkey: hkey };\n", + " },\n", + " enumerable: true,\n", + " configurable: true\n", + " });\n", + " ParallelSelectionView.prototype._emit_cds_changes = function (cds, redraw, clear, emit) {\n", + " if (redraw === void 0) { redraw = true; }\n", + " if (clear === void 0) { clear = true; }\n", + " if (emit === void 0) { emit = true; }\n", + " if (clear)\n", + " cds.selection_manager.clear();\n", + " if (redraw)\n", + " cds.change.emit();\n", + " if (emit) {\n", + " cds.data = cds.data;\n", + " cds.properties.data.change.emit();\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._box_paramaters = function (index) {\n", + " var _a = this._cds_select_keys, xkey = _a.xkey, ykey = _a.ykey, wkey = _a.wkey, hkey = _a.hkey;\n", + " var x = this.cds_select.get_array(xkey)[index];\n", + " var y = this.cds_select.get_array(ykey)[index];\n", + " var w = this.cds_select.get_array(wkey)[index];\n", + " var h = this.cds_select.get_array(hkey)[index];\n", + " return { x: x, y: y, w: w, h: h };\n", + " };\n", + " ParallelSelectionView.prototype._hit_test_boxes = function (sx, sy) {\n", + " var nboxes = this.cds_select.get_length();\n", + " if (nboxes != 0 && nboxes != null) {\n", + " var _a = [this.xscale.invert(sx), this.yscale.invert(sy)], xtest = _a[0], ytest = _a[1];\n", + " for (var i = 0; i < nboxes; i++) {\n", + " var _b = this._box_paramaters(i), x = _b.x, y = _b.y, w = _b.w, h = _b.h;\n", + " if (xtest >= (x - w / 2) && xtest <= x + w / 2 &&\n", + " ytest >= (y - h / 2) && ytest <= y + h / 2) {\n", + " return i;\n", + " }\n", + " }\n", + " }\n", + " return null;\n", + " };\n", + " ParallelSelectionView.prototype._resize_boxes_on_zoom = function () {\n", + " //resize selection boxes when zooming to keep a constant (pixel) size\n", + " var cds = this.cds_select;\n", + " var array_width = cds.get_array(this.glyph_select.width.field);\n", + " var new_width = this._box_width;\n", + " array_width.forEach(function (_, i) { return array_width[i] = new_width; });\n", + " this._emit_cds_changes(cds, true, false, false);\n", + " };\n", + " ParallelSelectionView.prototype._drag_start = function (ev) {\n", + " //Save y position of the drag start\n", + " if (this.ind_active_box != null) {\n", + " this._base_point = [this.xscale.invert(ev.sx), this.yscale.invert(ev.sy)];\n", + " this._base_box_parameters = this._box_paramaters(this.ind_active_box);\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._update_box_ypos = function (index_box, delta_y) {\n", + " if (this._base_box_parameters != null) {\n", + " var cds = this.cds_select;\n", + " var ykey = this._cds_select_keys.ykey;\n", + " var _a = this._base_box_parameters, current_y = _a.y, h = _a.h;\n", + " var new_y = current_y + delta_y;\n", + " new_y = new_y - Math.max(0, (new_y + h / 2) - 1) - Math.min(0, (new_y - h / 2));\n", + " cds.get_array(ykey)[index_box] = new_y;\n", + " this._emit_cds_changes(cds, true, false, false);\n", + " this._update_selection_indices(index_box, [new_y - h / 2, new_y + h / 2]);\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._drag = function (ev) {\n", + " if (this.ind_active_box != null && this._base_point != null) {\n", + " var delta_y = this.yscale.invert(ev.sy) - this._base_point[1];\n", + " this._update_box_ypos(this.ind_active_box, delta_y);\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._drag_stop = function (_ev) {\n", + " this._base_point = null;\n", + " this._base_box_parameters = null;\n", + " };\n", + " ParallelSelectionView.prototype._pan_start = function (ev) {\n", + " this.panning = true;\n", + " switch (this.selection_mode) {\n", + " case \"add\": {\n", + " _super.prototype._pan_start.call(this, ev);\n", + " break;\n", + " }\n", + " case \"drag\": {\n", + " this._drag_start(ev);\n", + " break;\n", + " }\n", + " case \"resize\": {\n", + " break;\n", + " }\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._pan = function (ev) {\n", + " switch (this.selection_mode) {\n", + " case \"add\": {\n", + " _super.prototype._pan.call(this, ev);\n", + " break;\n", + " }\n", + " case \"drag\": {\n", + " this._drag(ev);\n", + " break;\n", + " }\n", + " case \"resize\": {\n", + " break;\n", + " }\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._pan_end = function (ev) {\n", + " switch (this.selection_mode) {\n", + " case \"add\": {\n", + " _super.prototype._pan_end.call(this, ev);\n", + " break;\n", + " }\n", + " case \"drag\": {\n", + " this._drag_stop(ev);\n", + " break;\n", + " }\n", + " case \"resize\": {\n", + " break;\n", + " }\n", + " }\n", + " this.panning = false;\n", + " };\n", + " ParallelSelectionView.prototype._move = function (ev) {\n", + " //Switch mode\n", + " if (this.panning) {\n", + " return;\n", + " }\n", + " this.ind_active_box = this._hit_test_boxes(ev.sx, ev.sy);\n", + " if (this.ind_active_box != null) {\n", + " this.selection_mode = \"drag\";\n", + " }\n", + " else {\n", + " this.selection_mode = \"add\";\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._doubletap = function (_ev) {\n", + " var _this = this;\n", + " //delete box on double tap\n", + " if (this.ind_active_box != null) {\n", + " this.cds_select.columns().forEach(function (key) {\n", + " _this.cds_select.get_array(key).splice(_this.ind_active_box, 1);\n", + " });\n", + " this._delete_selection_indices(this.ind_active_box);\n", + " this._emit_cds_changes(this.cds_select);\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._keyup = function (ev) {\n", + " var _this = this;\n", + " if (ev.keyCode == dom_1.Keys.Esc) {\n", + " var nelems_1 = this.cds_select.get_length();\n", + " if (nelems_1 != null) {\n", + " this.cds_select.columns().forEach(function (key) {\n", + " _this.cds_select.get_array(key).splice(0, nelems_1);\n", + " });\n", + " this.selection_indices.splice(0, nelems_1);\n", + " this._emit_cds_changes(this.cds_select);\n", + " }\n", + " this.plot_view.request_render();\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._update_data_selection = function () {\n", + " var selection_indices = [];\n", + " if (this.selection_indices.length > 0) {\n", + " var combined_selections = combineByKey('data_idx', this.selection_indices);\n", + " selection_indices = array_1.intersection.apply(void 0, [array_1.union.apply(void 0, combined_selections[0].indices)].concat(combined_selections.slice(1).map(function (elem) { return array_1.union.apply(void 0, elem.indices); })));\n", + " }\n", + " this.cds_data.selected.indices = selection_indices;\n", + " this.cds_data.change.emit();\n", + " };\n", + " ParallelSelectionView.prototype._make_selection_indices = function (indices, _a) {\n", + " var _this = this;\n", + " var _b;\n", + " var y0 = _a[0], y1 = _a[1];\n", + " (_b = this.selection_indices).push.apply(_b, indices.map(function (index) {\n", + " return {\n", + " data_idx: index,\n", + " indices: find_indices_in(_this.ydataT[index], [y0, y1]),\n", + " };\n", + " }));\n", + " };\n", + " ParallelSelectionView.prototype._update_selection_indices = function (index, _a) {\n", + " var y0 = _a[0], y1 = _a[1];\n", + " this.selection_indices[index].indices = find_indices_in(this.ydataT[this.selection_indices[index].data_idx], [y0, y1]);\n", + " };\n", + " ParallelSelectionView.prototype._delete_selection_indices = function (index) {\n", + " this.selection_indices.splice(index, 1);\n", + " };\n", + " ParallelSelectionView.prototype._make_box_select = function (xs, _a) {\n", + " var _this = this;\n", + " var y0 = _a[0], y1 = _a[1];\n", + " y0 = Math.max(0, y0);\n", + " y1 = Math.min(1, y1);\n", + " var y = (y0 + y1) / 2.;\n", + " var w = this._box_width;\n", + " var h = y1 - y0;\n", + " var _b = this._cds_select_keys, xkey = _b.xkey, ykey = _b.ykey, wkey = _b.wkey, hkey = _b.hkey;\n", + " xs.forEach(function (x) {\n", + " if (xkey)\n", + " _this.cds_select.get_array(xkey).push(x);\n", + " if (ykey)\n", + " _this.cds_select.get_array(ykey).push(y);\n", + " if (wkey)\n", + " _this.cds_select.get_array(wkey).push(w);\n", + " if (hkey)\n", + " _this.cds_select.get_array(hkey).push(h);\n", + " });\n", + " this._emit_cds_changes(this.cds_select);\n", + " };\n", + " ParallelSelectionView.prototype._do_select = function (_a, _b, _final, _append) {\n", + " var sx0 = _a[0], sx1 = _a[1];\n", + " var sy0 = _b[0], sy1 = _b[1];\n", + " if (_final === void 0) { _final = true; }\n", + " if (_append === void 0) { _append = true; }\n", + " // Get selection bbox in the data space\n", + " var _c = this.xscale.r_invert(sx0, sx1), x0 = _c[0], x1 = _c[1];\n", + " var _d = this.yscale.r_invert(sy0, sy1), y0 = _d[0], y1 = _d[1];\n", + " var x_indices = find_indices_in(this.xdata, [x0, x1]);\n", + " var xs = index_array(this.xdata, x_indices);\n", + " this._make_selection_indices(x_indices, [y0, y1]);\n", + " this._make_box_select(xs, [y0, y1]);\n", + " };\n", + " return ParallelSelectionView;\n", + " }(box_select_tool_1.BoxSelectToolView));\n", + " exports.ParallelSelectionView = ParallelSelectionView;\n", + " var ParallelSelectionTool = /** @class */ (function (_super) {\n", + " __extends(ParallelSelectionTool, _super);\n", + " function ParallelSelectionTool() {\n", + " var _this = _super !== null && _super.apply(this, arguments) || this;\n", + " _this.tool_name = \"Parallel Selection\";\n", + " //override event_type property define in BoxSelectTool\n", + " _this.event_type = [\"tap\", \"pan\", \"move\"];\n", + " return _this;\n", + " }\n", + " ParallelSelectionTool.initClass = function () {\n", + " this.prototype.type = \"ParallelSelectionTool\";\n", + " this.prototype.default_view = ParallelSelectionView;\n", + " this.define({\n", + " renderer_select: [p.Any],\n", + " renderer_data: [p.Any],\n", + " box_width: [p.Number, 30],\n", + " });\n", + " };\n", + " return ParallelSelectionTool;\n", + " }(box_select_tool_1.BoxSelectTool));\n", + " exports.ParallelSelectionTool = ParallelSelectionTool;\n", + " ParallelSelectionTool.initClass();\n", + "\n", + " }\n", + " }, \"custom/main\");\n", + " ;\n", + " });\n", + "\n", + " },\n", + " function(Bokeh) {} // ensure no trailing comma for IE\n", + " ];\n", + "\n", + " function run_inline_js() {\n", + " \n", + " if ((root.Bokeh !== undefined) || (force === true)) {\n", + " for (var i = 0; i < inline_js.length; i++) {\n", + " inline_js[i].call(root, root.Bokeh);\n", + " }if (force === true) {\n", + " display_loaded();\n", + " }} else if (Date.now() < root._bokeh_timeout) {\n", + " setTimeout(run_inline_js, 100);\n", + " } else if (!root._bokeh_failed_load) {\n", + " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", + " root._bokeh_failed_load = true;\n", + " } else if (force !== true) {\n", + " var cell = $(document.getElementById(\"5122\")).parents('.cell').data().cell;\n", + " cell.output_area.append_execute_result(NB_LOAD_WARNING)\n", + " }\n", + "\n", + " }\n", + "\n", + " if (root._bokeh_is_loading === 0) {\n", + " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", + " run_inline_js();\n", + " } else {\n", + " load_libs(css_urls, js_urls, function() {\n", + " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", + " run_inline_js();\n", + " });\n", + " }\n", + "}(window));" + ], + "application/vnd.bokehjs_load.v0+json": "\n(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n \n\n \n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n var NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n var el = document.getElementById(\"5122\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };var element = document.getElementById(\"5122\");\n if (element == null) {\n console.error(\"Bokeh: ERROR: autoload.js configured with elementid '5122' but no matching script tag was found. \")\n return false;\n }\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.1.0.min.js\"];\n var css_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.css\"];\n\n var inline_js = [\n function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n \n function(Bokeh) {\n (function(root, factory) {\n // if(typeof exports === 'object' && typeof module === 'object')\n // factory(require(\"Bokeh\"));\n // else if(typeof define === 'function' && define.amd)\n // define([\"Bokeh\"], factory);\n // else if(typeof exports === 'object')\n // factory(require(\"Bokeh\"));\n // else\n factory(root[\"Bokeh\"]);\n })(this, function(Bokeh) {\n var define;\n return (function outer(modules, entry) {\n if (Bokeh != null) {\n return Bokeh.register_plugin(modules, {}, entry);\n } else {\n throw new Error(\"Cannot find Bokeh. You have to load it prior to loading plugins.\");\n }\n })\n ({\n \"custom/main\": function(require, module, exports) {\n var models = {\n \"ParallelResetTool\": require(\"custom/cave.plot.parallel_plot.parallel_reset.parallel_reset_tool\").ParallelResetTool,\n \"ParallelSelectionTool\": require(\"custom/cave.plot.parallel_plot.parallel_selection_tool.parallel_selection_tool\").ParallelSelectionTool\n };\n require(\"base\").register_models(models);\n module.exports = models;\n },\n \"custom/cave.plot.parallel_plot.parallel_reset.parallel_reset_tool\": function(require, module, exports) {\n \"use strict\";\n var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n })();\n Object.defineProperty(exports, \"__esModule\", { value: true });\n var action_tool_1 = require(\"models/tools/actions/action_tool\");\n var ParallelResetToolView = /** @class */ (function (_super) {\n __extends(ParallelResetToolView, _super);\n function ParallelResetToolView() {\n return _super !== null && _super.apply(this, arguments) || this;\n }\n ParallelResetToolView.prototype.doit = function () {\n this.plot_view.reset_range();\n };\n return ParallelResetToolView;\n }(action_tool_1.ActionToolView));\n exports.ParallelResetToolView = ParallelResetToolView;\n var ParallelResetTool = /** @class */ (function (_super) {\n __extends(ParallelResetTool, _super);\n function ParallelResetTool(attrs) {\n var _this = _super.call(this, attrs) || this;\n _this.tool_name = \"Reset Zoom\";\n _this.icon = \"bk-tool-icon-reset\";\n return _this;\n }\n ParallelResetTool.initClass = function () {\n this.prototype.type = \"ParallelResetTool\";\n this.prototype.default_view = ParallelResetToolView;\n };\n return ParallelResetTool;\n }(action_tool_1.ActionTool));\n exports.ParallelResetTool = ParallelResetTool;\n ParallelResetTool.initClass();\n\n },\n \"custom/cave.plot.parallel_plot.parallel_selection_tool.parallel_selection_tool\": function(require, module, exports) {\n \"use strict\";\n var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n })();\n Object.defineProperty(exports, \"__esModule\", { value: true });\n var p = require(\"core/properties\");\n var box_select_tool_1 = require(\"models/tools/gestures/box_select_tool\");\n var array_1 = require(\"core/util/array\");\n var dom_1 = require(\"core/dom\");\n function find_indices_in(array, _a) {\n var inf = _a[0], sup = _a[1];\n return array.reduce(function (prev, curr, index) {\n return (inf <= curr && curr <= sup) ? prev.concat(index) : prev;\n }, []);\n }\n function index_array(array, indices) {\n return indices.reduce(function (a, i) { return a.concat(array[i]); }, []);\n }\n function combineByKey(key, array) {\n var keys = Object.keys(array[0]);\n var combined = [];\n array.forEach(function (itm) {\n var idx = combined.map(function (item) { return item[key]; }).indexOf(itm[key]);\n if (idx >= 0) {\n keys.forEach(function (element) {\n if (element != key)\n combined[idx][element].push(itm[element]);\n });\n }\n else {\n var new_object_1 = {};\n keys.forEach(function (element) {\n if (element == key) {\n new_object_1[element] = itm[element];\n }\n else {\n new_object_1[element] = [itm[element]];\n }\n });\n combined.push(new_object_1);\n }\n });\n return combined;\n }\n var ParallelSelectionView = /** @class */ (function (_super) {\n __extends(ParallelSelectionView, _super);\n function ParallelSelectionView() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n _this.selection_mode = \"add\";\n _this.panning = false;\n return _this;\n }\n ParallelSelectionView.prototype.initialize = function () {\n var _this = this;\n _super.prototype.initialize.call(this);\n var frame = this.plot_view.frame;\n var _a = this.model.renderer_select, x_range_name_select = _a.x_range_name, y_range_name_select = _a.y_range_name;\n var _b = this.model.renderer_data, x_range_name_data = _b.x_range_name, y_range_name_data = _b.y_range_name;\n if (x_range_name_select == x_range_name_data && y_range_name_select == y_range_name_data) {\n this.xscale = frame.xscales[x_range_name_select];\n this.yscale = frame.yscales[y_range_name_select];\n }\n else\n throw new Error(\"selection and data does not share the same ranges\");\n //TODO test if parallel CDS is valid (xs for each line should be identical)\n this.glyph_select = this.model.renderer_select.glyph;\n this.glyph_data = this.model.renderer_data.glyph;\n this.cds_select = this.model.renderer_select.data_source;\n this.cds_data = this.model.renderer_data.data_source;\n var _c = [this.glyph_data.xs.field, this.glyph_data.ys.field], xskey = _c[0], yskey = _c[1];\n this.xdata = this.cds_data.get_array(xskey)[0];\n this.ydataT = array_1.transpose(this.cds_data.get_array(yskey));\n this.selection_indices = [];\n this.connect(this.plot_view.frame.x_ranges[this.model.renderer_select.x_range_name].change, function () { return _this._resize_boxes_on_zoom(); });\n this.connect(this.cds_select.change, function () { return _this._update_data_selection(); });\n };\n Object.defineProperty(ParallelSelectionView.prototype, \"_box_width\", {\n get: function () {\n return this.xscale.invert(this.model.box_width) - this.xscale.invert(0);\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(ParallelSelectionView.prototype, \"_cds_select_keys\", {\n get: function () {\n var glyph_select = this.glyph_select;\n var _a = [glyph_select.x.field, glyph_select.y.field], xkey = _a[0], ykey = _a[1];\n var _b = [glyph_select.width.field, glyph_select.height.field], wkey = _b[0], hkey = _b[1];\n return { xkey: xkey, ykey: ykey, wkey: wkey, hkey: hkey };\n },\n enumerable: true,\n configurable: true\n });\n ParallelSelectionView.prototype._emit_cds_changes = function (cds, redraw, clear, emit) {\n if (redraw === void 0) { redraw = true; }\n if (clear === void 0) { clear = true; }\n if (emit === void 0) { emit = true; }\n if (clear)\n cds.selection_manager.clear();\n if (redraw)\n cds.change.emit();\n if (emit) {\n cds.data = cds.data;\n cds.properties.data.change.emit();\n }\n };\n ParallelSelectionView.prototype._box_paramaters = function (index) {\n var _a = this._cds_select_keys, xkey = _a.xkey, ykey = _a.ykey, wkey = _a.wkey, hkey = _a.hkey;\n var x = this.cds_select.get_array(xkey)[index];\n var y = this.cds_select.get_array(ykey)[index];\n var w = this.cds_select.get_array(wkey)[index];\n var h = this.cds_select.get_array(hkey)[index];\n return { x: x, y: y, w: w, h: h };\n };\n ParallelSelectionView.prototype._hit_test_boxes = function (sx, sy) {\n var nboxes = this.cds_select.get_length();\n if (nboxes != 0 && nboxes != null) {\n var _a = [this.xscale.invert(sx), this.yscale.invert(sy)], xtest = _a[0], ytest = _a[1];\n for (var i = 0; i < nboxes; i++) {\n var _b = this._box_paramaters(i), x = _b.x, y = _b.y, w = _b.w, h = _b.h;\n if (xtest >= (x - w / 2) && xtest <= x + w / 2 &&\n ytest >= (y - h / 2) && ytest <= y + h / 2) {\n return i;\n }\n }\n }\n return null;\n };\n ParallelSelectionView.prototype._resize_boxes_on_zoom = function () {\n //resize selection boxes when zooming to keep a constant (pixel) size\n var cds = this.cds_select;\n var array_width = cds.get_array(this.glyph_select.width.field);\n var new_width = this._box_width;\n array_width.forEach(function (_, i) { return array_width[i] = new_width; });\n this._emit_cds_changes(cds, true, false, false);\n };\n ParallelSelectionView.prototype._drag_start = function (ev) {\n //Save y position of the drag start\n if (this.ind_active_box != null) {\n this._base_point = [this.xscale.invert(ev.sx), this.yscale.invert(ev.sy)];\n this._base_box_parameters = this._box_paramaters(this.ind_active_box);\n }\n };\n ParallelSelectionView.prototype._update_box_ypos = function (index_box, delta_y) {\n if (this._base_box_parameters != null) {\n var cds = this.cds_select;\n var ykey = this._cds_select_keys.ykey;\n var _a = this._base_box_parameters, current_y = _a.y, h = _a.h;\n var new_y = current_y + delta_y;\n new_y = new_y - Math.max(0, (new_y + h / 2) - 1) - Math.min(0, (new_y - h / 2));\n cds.get_array(ykey)[index_box] = new_y;\n this._emit_cds_changes(cds, true, false, false);\n this._update_selection_indices(index_box, [new_y - h / 2, new_y + h / 2]);\n }\n };\n ParallelSelectionView.prototype._drag = function (ev) {\n if (this.ind_active_box != null && this._base_point != null) {\n var delta_y = this.yscale.invert(ev.sy) - this._base_point[1];\n this._update_box_ypos(this.ind_active_box, delta_y);\n }\n };\n ParallelSelectionView.prototype._drag_stop = function (_ev) {\n this._base_point = null;\n this._base_box_parameters = null;\n };\n ParallelSelectionView.prototype._pan_start = function (ev) {\n this.panning = true;\n switch (this.selection_mode) {\n case \"add\": {\n _super.prototype._pan_start.call(this, ev);\n break;\n }\n case \"drag\": {\n this._drag_start(ev);\n break;\n }\n case \"resize\": {\n break;\n }\n }\n };\n ParallelSelectionView.prototype._pan = function (ev) {\n switch (this.selection_mode) {\n case \"add\": {\n _super.prototype._pan.call(this, ev);\n break;\n }\n case \"drag\": {\n this._drag(ev);\n break;\n }\n case \"resize\": {\n break;\n }\n }\n };\n ParallelSelectionView.prototype._pan_end = function (ev) {\n switch (this.selection_mode) {\n case \"add\": {\n _super.prototype._pan_end.call(this, ev);\n break;\n }\n case \"drag\": {\n this._drag_stop(ev);\n break;\n }\n case \"resize\": {\n break;\n }\n }\n this.panning = false;\n };\n ParallelSelectionView.prototype._move = function (ev) {\n //Switch mode\n if (this.panning) {\n return;\n }\n this.ind_active_box = this._hit_test_boxes(ev.sx, ev.sy);\n if (this.ind_active_box != null) {\n this.selection_mode = \"drag\";\n }\n else {\n this.selection_mode = \"add\";\n }\n };\n ParallelSelectionView.prototype._doubletap = function (_ev) {\n var _this = this;\n //delete box on double tap\n if (this.ind_active_box != null) {\n this.cds_select.columns().forEach(function (key) {\n _this.cds_select.get_array(key).splice(_this.ind_active_box, 1);\n });\n this._delete_selection_indices(this.ind_active_box);\n this._emit_cds_changes(this.cds_select);\n }\n };\n ParallelSelectionView.prototype._keyup = function (ev) {\n var _this = this;\n if (ev.keyCode == dom_1.Keys.Esc) {\n var nelems_1 = this.cds_select.get_length();\n if (nelems_1 != null) {\n this.cds_select.columns().forEach(function (key) {\n _this.cds_select.get_array(key).splice(0, nelems_1);\n });\n this.selection_indices.splice(0, nelems_1);\n this._emit_cds_changes(this.cds_select);\n }\n this.plot_view.request_render();\n }\n };\n ParallelSelectionView.prototype._update_data_selection = function () {\n var selection_indices = [];\n if (this.selection_indices.length > 0) {\n var combined_selections = combineByKey('data_idx', this.selection_indices);\n selection_indices = array_1.intersection.apply(void 0, [array_1.union.apply(void 0, combined_selections[0].indices)].concat(combined_selections.slice(1).map(function (elem) { return array_1.union.apply(void 0, elem.indices); })));\n }\n this.cds_data.selected.indices = selection_indices;\n this.cds_data.change.emit();\n };\n ParallelSelectionView.prototype._make_selection_indices = function (indices, _a) {\n var _this = this;\n var _b;\n var y0 = _a[0], y1 = _a[1];\n (_b = this.selection_indices).push.apply(_b, indices.map(function (index) {\n return {\n data_idx: index,\n indices: find_indices_in(_this.ydataT[index], [y0, y1]),\n };\n }));\n };\n ParallelSelectionView.prototype._update_selection_indices = function (index, _a) {\n var y0 = _a[0], y1 = _a[1];\n this.selection_indices[index].indices = find_indices_in(this.ydataT[this.selection_indices[index].data_idx], [y0, y1]);\n };\n ParallelSelectionView.prototype._delete_selection_indices = function (index) {\n this.selection_indices.splice(index, 1);\n };\n ParallelSelectionView.prototype._make_box_select = function (xs, _a) {\n var _this = this;\n var y0 = _a[0], y1 = _a[1];\n y0 = Math.max(0, y0);\n y1 = Math.min(1, y1);\n var y = (y0 + y1) / 2.;\n var w = this._box_width;\n var h = y1 - y0;\n var _b = this._cds_select_keys, xkey = _b.xkey, ykey = _b.ykey, wkey = _b.wkey, hkey = _b.hkey;\n xs.forEach(function (x) {\n if (xkey)\n _this.cds_select.get_array(xkey).push(x);\n if (ykey)\n _this.cds_select.get_array(ykey).push(y);\n if (wkey)\n _this.cds_select.get_array(wkey).push(w);\n if (hkey)\n _this.cds_select.get_array(hkey).push(h);\n });\n this._emit_cds_changes(this.cds_select);\n };\n ParallelSelectionView.prototype._do_select = function (_a, _b, _final, _append) {\n var sx0 = _a[0], sx1 = _a[1];\n var sy0 = _b[0], sy1 = _b[1];\n if (_final === void 0) { _final = true; }\n if (_append === void 0) { _append = true; }\n // Get selection bbox in the data space\n var _c = this.xscale.r_invert(sx0, sx1), x0 = _c[0], x1 = _c[1];\n var _d = this.yscale.r_invert(sy0, sy1), y0 = _d[0], y1 = _d[1];\n var x_indices = find_indices_in(this.xdata, [x0, x1]);\n var xs = index_array(this.xdata, x_indices);\n this._make_selection_indices(x_indices, [y0, y1]);\n this._make_box_select(xs, [y0, y1]);\n };\n return ParallelSelectionView;\n }(box_select_tool_1.BoxSelectToolView));\n exports.ParallelSelectionView = ParallelSelectionView;\n var ParallelSelectionTool = /** @class */ (function (_super) {\n __extends(ParallelSelectionTool, _super);\n function ParallelSelectionTool() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n _this.tool_name = \"Parallel Selection\";\n //override event_type property define in BoxSelectTool\n _this.event_type = [\"tap\", \"pan\", \"move\"];\n return _this;\n }\n ParallelSelectionTool.initClass = function () {\n this.prototype.type = \"ParallelSelectionTool\";\n this.prototype.default_view = ParallelSelectionView;\n this.define({\n renderer_select: [p.Any],\n renderer_data: [p.Any],\n box_width: [p.Number, 30],\n });\n };\n return ParallelSelectionTool;\n }(box_select_tool_1.BoxSelectTool));\n exports.ParallelSelectionTool = ParallelSelectionTool;\n ParallelSelectionTool.initClass();\n\n }\n }, \"custom/main\");\n ;\n });\n\n },\n function(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n \n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }if (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n var cell = $(document.getElementById(\"5122\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "(function(root) {\n", + " function embed_document(root) {\n", + " \n", + " var docs_json = {\"b4b772c4-59a0-4ce0-8e85-e1b915319642\":{\"roots\":{\"references\":[{\"attributes\":{\"children\":[{\"id\":\"5125\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"id\":\"5193\",\"type\":\"Column\"}]},\"id\":\"5194\",\"type\":\"Row\"},{\"attributes\":{\"line_color\":\"#d95f02\",\"x\":{\"field\":\"time\"},\"y\":{\"field\":\"mean\"}},\"id\":\"5170\",\"type\":\"Line\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#1f77b4\",\"x\":{\"field\":\"time\"},\"y\":{\"field\":\"mean\"}},\"id\":\"5160\",\"type\":\"Line\"},{\"attributes\":{\"active\":[0],\"callback\":{\"id\":\"5180\",\"type\":\"CustomJS\"},\"labels\":[\"all budgets\",\"budget_20000\"]},\"id\":\"5181\",\"type\":\"CheckboxButtonGroup\"},{\"attributes\":{\"data_source\":{\"id\":\"5123\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"5159\",\"type\":\"Line\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"5160\",\"type\":\"Line\"},\"selection_glyph\":null,\"view\":{\"id\":\"5157\",\"type\":\"CDSView\"}},\"id\":\"5161\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"children\":[{\"id\":\"5190\",\"type\":\"WidgetBox\"},{\"id\":\"5191\",\"type\":\"WidgetBox\"}]},\"id\":\"5192\",\"type\":\"Row\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#1f77b4\",\"x\":{\"field\":\"time\"},\"y\":{\"field\":\"mean\"}},\"id\":\"5171\",\"type\":\"Line\"},{\"attributes\":{\"children\":[{\"id\":\"5189\",\"type\":\"WidgetBox\"},{\"id\":\"5192\",\"type\":\"Row\"}]},\"id\":\"5193\",\"type\":\"Column\"},{\"attributes\":{\"data_source\":{\"id\":\"5123\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"5170\",\"type\":\"Line\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"5171\",\"type\":\"Line\"},\"selection_glyph\":null,\"view\":{\"id\":\"5168\",\"type\":\"CDSView\"},\"visible\":false},\"id\":\"5172\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"callback\":null,\"data\":{\"x\":{\"__ndarray__\":\"AAAAAAAA8D8AAAAAAADwPw==\",\"dtype\":\"float64\",\"shape\":[2]},\"y\":{\"__ndarray__\":\"OrTIdr4PVsA6tMh2vg9WwA==\",\"dtype\":\"float64\",\"shape\":[2]}},\"selected\":{\"id\":\"5204\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"5203\",\"type\":\"UnionRenderers\"}},\"id\":\"5162\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"args\":{\"checkbox\":{\"id\":\"5181\",\"type\":\"CheckboxButtonGroup\"},\"glyph_renderer0\":{\"id\":\"5161\",\"type\":\"GlyphRenderer\"},\"glyph_renderer1\":{\"id\":\"5165\",\"type\":\"GlyphRenderer\"},\"glyph_renderer2\":{\"id\":\"5172\",\"type\":\"GlyphRenderer\"},\"glyph_renderer3\":{\"id\":\"5176\",\"type\":\"GlyphRenderer\"}},\"code\":\"var labels = []; checkbox.active = labels;len_labels = 2;glyph_renderers = [[glyph_renderer0,glyph_renderer1],[glyph_renderer2,glyph_renderer3]];\\n for (i = 0; i < len_labels; i++) {\\n if (checkbox.active.includes(i)) {\\n // console.log('Setting to true: ' + i + '(' + glyph_renderers[i].length + ')')\\n for (j = 0; j < glyph_renderers[i].length; j++) {\\n glyph_renderers[i][j].visible = true;\\n // console.log('Setting to true: ' + i + ' : ' + j)\\n }\\n } else {\\n // console.log('Setting to false: ' + i + '(' + glyph_renderers[i].length + ')')\\n for (j = 0; j < glyph_renderers[i].length; j++) {\\n glyph_renderers[i][j].visible = false;\\n // console.log('Setting to false: ' + i + ' : ' + j)\\n }\\n }\\n }\\n \"},\"id\":\"5184\",\"type\":\"CustomJS\"},{\"attributes\":{\"data_source\":{\"id\":\"5162\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"5163\",\"type\":\"Patch\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"5164\",\"type\":\"Patch\"},\"selection_glyph\":null,\"view\":{\"id\":\"5166\",\"type\":\"CDSView\"}},\"id\":\"5165\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"callback\":null},\"id\":\"5129\",\"type\":\"DataRange1d\"},{\"attributes\":{\"fill_alpha\":0.2,\"fill_color\":\"#7570B3\",\"line_color\":\"#7570B3\",\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"5163\",\"type\":\"Patch\"},{\"attributes\":{},\"id\":\"5131\",\"type\":\"LogScale\"},{\"attributes\":{\"fill_alpha\":0.1,\"fill_color\":\"#1f77b4\",\"line_alpha\":0.1,\"line_color\":\"#1f77b4\",\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"5164\",\"type\":\"Patch\"},{\"attributes\":{},\"id\":\"5133\",\"type\":\"LinearScale\"},{\"attributes\":{\"children\":[{\"id\":\"5185\",\"type\":\"Button\"}],\"width\":50},\"id\":\"5191\",\"type\":\"WidgetBox\"},{\"attributes\":{\"axis_label\":\"time (sec)\",\"axis_label_text_font_size\":{\"value\":\"15pt\"},\"formatter\":{\"id\":\"5196\",\"type\":\"LogTickFormatter\"},\"major_label_orientation\":0.75,\"major_label_text_font_size\":{\"value\":\"12pt\"},\"ticker\":{\"id\":\"5136\",\"type\":\"LogTicker\"}},\"id\":\"5135\",\"type\":\"LogAxis\"},{\"attributes\":{},\"id\":\"5149\",\"type\":\"ResetTool\"},{\"attributes\":{},\"id\":\"5204\",\"type\":\"Selection\"},{\"attributes\":{\"callback\":{\"id\":\"5184\",\"type\":\"CustomJS\"},\"icon\":null,\"label\":\"None\"},\"id\":\"5185\",\"type\":\"Button\"},{\"attributes\":{\"num_minor_ticks\":10},\"id\":\"5136\",\"type\":\"LogTicker\"},{\"attributes\":{},\"id\":\"5205\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"args\":{\"glyph_renderer0\":{\"id\":\"5161\",\"type\":\"GlyphRenderer\"},\"glyph_renderer1\":{\"id\":\"5165\",\"type\":\"GlyphRenderer\"},\"glyph_renderer2\":{\"id\":\"5172\",\"type\":\"GlyphRenderer\"},\"glyph_renderer3\":{\"id\":\"5176\",\"type\":\"GlyphRenderer\"}},\"code\":\"len_labels = 2;glyph_renderers = [[glyph_renderer0,glyph_renderer1],[glyph_renderer2,glyph_renderer3]];\\n for (i = 0; i < len_labels; i++) {\\n if (cb_obj.active.includes(i)) {\\n // console.log('Setting to true: ' + i + '(' + glyph_renderers[i].length + ')')\\n for (j = 0; j < glyph_renderers[i].length; j++) {\\n glyph_renderers[i][j].visible = true;\\n // console.log('Setting to true: ' + i + ' : ' + j)\\n }\\n } else {\\n // console.log('Setting to false: ' + i + '(' + glyph_renderers[i].length + ')')\\n for (j = 0; j < glyph_renderers[i].length; j++) {\\n glyph_renderers[i][j].visible = false;\\n // console.log('Setting to false: ' + i + ' : ' + j)\\n }\\n }\\n }\\n \"},\"id\":\"5180\",\"type\":\"CustomJS\"},{\"attributes\":{\"active_drag\":\"auto\",\"active_inspect\":\"auto\",\"active_multi\":null,\"active_scroll\":\"auto\",\"active_tap\":\"auto\",\"tools\":[{\"id\":\"5145\",\"type\":\"SaveTool\"},{\"id\":\"5146\",\"type\":\"PanTool\"},{\"id\":\"5147\",\"type\":\"BoxZoomTool\"},{\"id\":\"5148\",\"type\":\"WheelZoomTool\"},{\"id\":\"5149\",\"type\":\"ResetTool\"},{\"id\":\"5178\",\"type\":\"HoverTool\"}]},\"id\":\"5150\",\"type\":\"Toolbar\"},{\"attributes\":{\"children\":[{\"id\":\"5181\",\"type\":\"CheckboxButtonGroup\"}],\"width\":100},\"id\":\"5189\",\"type\":\"WidgetBox\"},{\"attributes\":{},\"id\":\"5206\",\"type\":\"Selection\"},{\"attributes\":{\"overlay\":{\"id\":\"5200\",\"type\":\"BoxAnnotation\"}},\"id\":\"5147\",\"type\":\"BoxZoomTool\"},{\"attributes\":{\"children\":[{\"id\":\"5183\",\"type\":\"Button\"}],\"width\":50},\"id\":\"5190\",\"type\":\"WidgetBox\"},{\"attributes\":{\"click_policy\":\"hide\",\"items\":[{\"id\":\"5187\",\"type\":\"LegendItem\"},{\"id\":\"5188\",\"type\":\"LegendItem\"}],\"label_text_font_size\":{\"value\":\"8pt\"},\"location\":\"bottom_left\"},\"id\":\"5186\",\"type\":\"Legend\"},{\"attributes\":{\"label\":{\"value\":\"all budgets\"},\"renderers\":[{\"id\":\"5161\",\"type\":\"GlyphRenderer\"},{\"id\":\"5165\",\"type\":\"GlyphRenderer\"}]},\"id\":\"5187\",\"type\":\"LegendItem\"},{\"attributes\":{\"callback\":null,\"data\":{\"delay\":[\"inactive\",\"inactive\",\"inactive\",\"inactive\"],\"lower\":[-88.24600000000001,-86.743,-86.743,-88.24600000000001],\"mean\":[-88.24600000000001,-86.743,-86.743,-88.24600000000001],\"name\":[\"all budgets\",\"budget_20000\",\"budget_20000\",\"budget_20000\"],\"sequence_length\":[\"inactive\",\"inactive\",\"inactive\",\"inactive\"],\"time\":[1.0,2.1,21.9,21.9],\"upper\":[-88.24600000000001,-86.743,-86.743,-88.24600000000001]},\"selected\":{\"id\":\"5202\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"5201\",\"type\":\"UnionRenderers\"}},\"id\":\"5123\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"line_color\":\"#1b9e77\",\"x\":{\"field\":\"time\"},\"y\":{\"field\":\"mean\"}},\"id\":\"5159\",\"type\":\"Line\"},{\"attributes\":{\"callback\":null,\"data\":{\"x\":{\"__ndarray__\":\"zczMzMzMAEBmZmZmZuY1QGZmZmZm5jVAZmZmZmbmNUBmZmZmZuY1QM3MzMzMzABA\",\"dtype\":\"float64\",\"shape\":[6]},\"y\":{\"__ndarray__\":\"ZDvfT42vVcBkO99Pja9VwDq0yHa+D1bAOrTIdr4PVsBkO99Pja9VwGQ730+Nr1XA\",\"dtype\":\"float64\",\"shape\":[6]}},\"selected\":{\"id\":\"5206\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"5205\",\"type\":\"UnionRenderers\"}},\"id\":\"5173\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"callback\":null,\"end\":21.9,\"start\":1.0},\"id\":\"5124\",\"type\":\"Range1d\"},{\"attributes\":{\"label\":{\"value\":\"budget_20000\"},\"renderers\":[{\"id\":\"5172\",\"type\":\"GlyphRenderer\"},{\"id\":\"5176\",\"type\":\"GlyphRenderer\"}]},\"id\":\"5188\",\"type\":\"LegendItem\"},{\"attributes\":{\"dimension\":1,\"ticker\":{\"id\":\"5141\",\"type\":\"BasicTicker\"}},\"id\":\"5144\",\"type\":\"Grid\"},{\"attributes\":{\"source\":{\"id\":\"5162\",\"type\":\"ColumnDataSource\"}},\"id\":\"5166\",\"type\":\"CDSView\"},{\"attributes\":{\"text\":\"Cost over time\",\"text_font_size\":{\"value\":\"15pt\"}},\"id\":\"5126\",\"type\":\"Title\"},{\"attributes\":{\"callback\":null,\"renderers\":[{\"id\":\"5161\",\"type\":\"GlyphRenderer\"},{\"id\":\"5165\",\"type\":\"GlyphRenderer\"},{\"id\":\"5172\",\"type\":\"GlyphRenderer\"},{\"id\":\"5176\",\"type\":\"GlyphRenderer\"}],\"tooltips\":[[\"estimated performance\",\"@mean\"],[\"at-time\",\"@time\"]]},\"id\":\"5178\",\"type\":\"HoverTool\"},{\"attributes\":{\"fill_alpha\":0.2,\"fill_color\":\"#7570B3\",\"line_color\":\"#7570B3\",\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"5174\",\"type\":\"Patch\"},{\"attributes\":{\"fill_alpha\":0.1,\"fill_color\":\"#1f77b4\",\"line_alpha\":0.1,\"line_color\":\"#1f77b4\",\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"5175\",\"type\":\"Patch\"},{\"attributes\":{},\"id\":\"5203\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"background_fill_color\":{\"value\":null},\"below\":[{\"id\":\"5135\",\"type\":\"LogAxis\"}],\"border_fill_color\":{\"value\":null},\"center\":[{\"id\":\"5139\",\"type\":\"Grid\"},{\"id\":\"5144\",\"type\":\"Grid\"}],\"left\":[{\"id\":\"5140\",\"type\":\"LinearAxis\"}],\"plot_height\":500,\"plot_width\":700,\"renderers\":[{\"id\":\"5161\",\"type\":\"GlyphRenderer\"},{\"id\":\"5165\",\"type\":\"GlyphRenderer\"},{\"id\":\"5172\",\"type\":\"GlyphRenderer\"},{\"id\":\"5176\",\"type\":\"GlyphRenderer\"}],\"right\":[{\"id\":\"5186\",\"type\":\"Legend\"}],\"title\":{\"id\":\"5126\",\"type\":\"Title\"},\"toolbar\":{\"id\":\"5150\",\"type\":\"Toolbar\"},\"x_range\":{\"id\":\"5124\",\"type\":\"Range1d\"},\"x_scale\":{\"id\":\"5131\",\"type\":\"LogScale\"},\"y_range\":{\"id\":\"5129\",\"type\":\"DataRange1d\"},\"y_scale\":{\"id\":\"5133\",\"type\":\"LinearScale\"}},\"id\":\"5125\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"attributes\":{\"ticker\":null},\"id\":\"5196\",\"type\":\"LogTickFormatter\"},{\"attributes\":{\"source\":{\"id\":\"5173\",\"type\":\"ColumnDataSource\"}},\"id\":\"5177\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"5198\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"column_name\":\"name\",\"group\":\"all budgets\"},\"id\":\"5156\",\"type\":\"GroupFilter\"},{\"attributes\":{\"args\":{\"checkbox\":{\"id\":\"5181\",\"type\":\"CheckboxButtonGroup\"},\"glyph_renderer0\":{\"id\":\"5161\",\"type\":\"GlyphRenderer\"},\"glyph_renderer1\":{\"id\":\"5165\",\"type\":\"GlyphRenderer\"},\"glyph_renderer2\":{\"id\":\"5172\",\"type\":\"GlyphRenderer\"},\"glyph_renderer3\":{\"id\":\"5176\",\"type\":\"GlyphRenderer\"}},\"code\":\"var labels = [0, 1]; checkbox.active = labels;len_labels = 2;glyph_renderers = [[glyph_renderer0,glyph_renderer1],[glyph_renderer2,glyph_renderer3]];\\n for (i = 0; i < len_labels; i++) {\\n if (checkbox.active.includes(i)) {\\n // console.log('Setting to true: ' + i + '(' + glyph_renderers[i].length + ')')\\n for (j = 0; j < glyph_renderers[i].length; j++) {\\n glyph_renderers[i][j].visible = true;\\n // console.log('Setting to true: ' + i + ' : ' + j)\\n }\\n } else {\\n // console.log('Setting to false: ' + i + '(' + glyph_renderers[i].length + ')')\\n for (j = 0; j < glyph_renderers[i].length; j++) {\\n glyph_renderers[i][j].visible = false;\\n // console.log('Setting to false: ' + i + ' : ' + j)\\n }\\n }\\n }\\n \"},\"id\":\"5182\",\"type\":\"CustomJS\"},{\"attributes\":{\"data_source\":{\"id\":\"5173\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"5174\",\"type\":\"Patch\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"5175\",\"type\":\"Patch\"},\"selection_glyph\":null,\"view\":{\"id\":\"5177\",\"type\":\"CDSView\"},\"visible\":false},\"id\":\"5176\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"ticker\":{\"id\":\"5136\",\"type\":\"LogTicker\"}},\"id\":\"5139\",\"type\":\"Grid\"},{\"attributes\":{\"filters\":[{\"id\":\"5156\",\"type\":\"GroupFilter\"}],\"source\":{\"id\":\"5123\",\"type\":\"ColumnDataSource\"}},\"id\":\"5157\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"5146\",\"type\":\"PanTool\"},{\"attributes\":{\"bottom_units\":\"screen\",\"fill_alpha\":{\"value\":0.5},\"fill_color\":{\"value\":\"lightgrey\"},\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":{\"value\":1.0},\"line_color\":{\"value\":\"black\"},\"line_dash\":[4,4],\"line_width\":{\"value\":2},\"render_mode\":\"css\",\"right_units\":\"screen\",\"top_units\":\"screen\"},\"id\":\"5200\",\"type\":\"BoxAnnotation\"},{\"attributes\":{},\"id\":\"5145\",\"type\":\"SaveTool\"},{\"attributes\":{},\"id\":\"5201\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"callback\":{\"id\":\"5182\",\"type\":\"CustomJS\"},\"icon\":null,\"label\":\"All\"},\"id\":\"5183\",\"type\":\"Button\"},{\"attributes\":{},\"id\":\"5202\",\"type\":\"Selection\"},{\"attributes\":{\"column_name\":\"name\",\"group\":\"budget_20000\"},\"id\":\"5167\",\"type\":\"GroupFilter\"},{\"attributes\":{},\"id\":\"5148\",\"type\":\"WheelZoomTool\"},{\"attributes\":{},\"id\":\"5141\",\"type\":\"BasicTicker\"},{\"attributes\":{\"filters\":[{\"id\":\"5167\",\"type\":\"GroupFilter\"}],\"source\":{\"id\":\"5123\",\"type\":\"ColumnDataSource\"}},\"id\":\"5168\",\"type\":\"CDSView\"},{\"attributes\":{\"axis_label\":\"estimated cost\",\"axis_label_text_font_size\":{\"value\":\"15pt\"},\"formatter\":{\"id\":\"5198\",\"type\":\"BasicTickFormatter\"},\"major_label_text_font_size\":{\"value\":\"12pt\"},\"ticker\":{\"id\":\"5141\",\"type\":\"BasicTicker\"}},\"id\":\"5140\",\"type\":\"LinearAxis\"}],\"root_ids\":[\"5194\"]},\"title\":\"Bokeh Application\",\"version\":\"1.1.0\"}};\n", + " var render_items = [{\"docid\":\"b4b772c4-59a0-4ce0-8e85-e1b915319642\",\"roots\":{\"5194\":\"3f4d416e-e533-4b9a-9a9c-ba2f11322549\"}}];\n", + " root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", + "\n", + " }\n", + " if (root.Bokeh !== undefined) {\n", + " embed_document(root);\n", + " } else {\n", + " var attempts = 0;\n", + " var timer = setInterval(function(root) {\n", + " if (root.Bokeh !== undefined) {\n", + " embed_document(root);\n", + " clearInterval(timer);\n", + " }\n", + " attempts++;\n", + " if (attempts > 100) {\n", + " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n", + " clearInterval(timer);\n", + " }\n", + " }, 10, root)\n", + " }\n", + "})(window);" + ], + "application/vnd.bokehjs_exec.v0+json": "" + }, + "metadata": { + "application/vnd.bokehjs_exec.v0+json": { + "id": "5194" + } + }, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cave.cost_over_time()" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
\n", + " \n", + " Loading BokehJS ...\n", + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "\n", + "(function(root) {\n", + " function now() {\n", + " return new Date();\n", + " }\n", + "\n", + " var force = true;\n", + "\n", + " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", + " root._bokeh_onload_callbacks = [];\n", + " root._bokeh_is_loading = undefined;\n", + " }\n", + "\n", + " var JS_MIME_TYPE = 'application/javascript';\n", + " var HTML_MIME_TYPE = 'text/html';\n", + " var EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n", + " var CLASS_NAME = 'output_bokeh rendered_html';\n", + "\n", + " /**\n", + " * Render data to the DOM node\n", + " */\n", + " function render(props, node) {\n", + " var script = document.createElement(\"script\");\n", + " node.appendChild(script);\n", + " }\n", + "\n", + " /**\n", + " * Handle when an output is cleared or removed\n", + " */\n", + " function handleClearOutput(event, handle) {\n", + " var cell = handle.cell;\n", + "\n", + " var id = cell.output_area._bokeh_element_id;\n", + " var server_id = cell.output_area._bokeh_server_id;\n", + " // Clean up Bokeh references\n", + " if (id != null && id in Bokeh.index) {\n", + " Bokeh.index[id].model.document.clear();\n", + " delete Bokeh.index[id];\n", + " }\n", + "\n", + " if (server_id !== undefined) {\n", + " // Clean up Bokeh references\n", + " var cmd = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n", + " cell.notebook.kernel.execute(cmd, {\n", + " iopub: {\n", + " output: function(msg) {\n", + " var id = msg.content.text.trim();\n", + " if (id in Bokeh.index) {\n", + " Bokeh.index[id].model.document.clear();\n", + " delete Bokeh.index[id];\n", + " }\n", + " }\n", + " }\n", + " });\n", + " // Destroy server and session\n", + " var cmd = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n", + " cell.notebook.kernel.execute(cmd);\n", + " }\n", + " }\n", + "\n", + " /**\n", + " * Handle when a new output is added\n", + " */\n", + " function handleAddOutput(event, handle) {\n", + " var output_area = handle.output_area;\n", + " var output = handle.output;\n", + "\n", + " // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n", + " if ((output.output_type != \"display_data\") || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", + " return\n", + " }\n", + "\n", + " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", + "\n", + " if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n", + " toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n", + " // store reference to embed id on output_area\n", + " output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", + " }\n", + " if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", + " var bk_div = document.createElement(\"div\");\n", + " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", + " var script_attrs = bk_div.children[0].attributes;\n", + " for (var i = 0; i < script_attrs.length; i++) {\n", + " toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n", + " }\n", + " // store reference to server id on output_area\n", + " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", + " }\n", + " }\n", + "\n", + " function register_renderer(events, OutputArea) {\n", + "\n", + " function append_mime(data, metadata, element) {\n", + " // create a DOM node to render to\n", + " var toinsert = this.create_output_subarea(\n", + " metadata,\n", + " CLASS_NAME,\n", + " EXEC_MIME_TYPE\n", + " );\n", + " this.keyboard_manager.register_events(toinsert);\n", + " // Render to node\n", + " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", + " render(props, toinsert[toinsert.length - 1]);\n", + " element.append(toinsert);\n", + " return toinsert\n", + " }\n", + "\n", + " /* Handle when an output is cleared or removed */\n", + " events.on('clear_output.CodeCell', handleClearOutput);\n", + " events.on('delete.Cell', handleClearOutput);\n", + "\n", + " /* Handle when a new output is added */\n", + " events.on('output_added.OutputArea', handleAddOutput);\n", + "\n", + " /**\n", + " * Register the mime type and append_mime function with output_area\n", + " */\n", + " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", + " /* Is output safe? */\n", + " safe: true,\n", + " /* Index of renderer in `output_area.display_order` */\n", + " index: 0\n", + " });\n", + " }\n", + "\n", + " // register the mime type if in Jupyter Notebook environment and previously unregistered\n", + " if (root.Jupyter !== undefined) {\n", + " var events = require('base/js/events');\n", + " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", + "\n", + " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", + " register_renderer(events, OutputArea);\n", + " }\n", + " }\n", + "\n", + " \n", + " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", + " root._bokeh_timeout = Date.now() + 5000;\n", + " root._bokeh_failed_load = false;\n", + " }\n", + "\n", + " var NB_LOAD_WARNING = {'data': {'text/html':\n", + " \"
\\n\"+\n", + " \"

\\n\"+\n", + " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", + " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", + " \"

\\n\"+\n", + " \"
    \\n\"+\n", + " \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n", + " \"
  • use INLINE resources instead, as so:
  • \\n\"+\n", + " \"
\\n\"+\n", + " \"\\n\"+\n", + " \"from bokeh.resources import INLINE\\n\"+\n", + " \"output_notebook(resources=INLINE)\\n\"+\n", + " \"\\n\"+\n", + " \"
\"}};\n", + "\n", + " function display_loaded() {\n", + " var el = document.getElementById(\"1246\");\n", + " if (el != null) {\n", + " el.textContent = \"BokehJS is loading...\";\n", + " }\n", + " if (root.Bokeh !== undefined) {\n", + " if (el != null) {\n", + " el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n", + " }\n", + " } else if (Date.now() < root._bokeh_timeout) {\n", + " setTimeout(display_loaded, 100)\n", + " }\n", + " }\n", + "\n", + "\n", + " function run_callbacks() {\n", + " try {\n", + " root._bokeh_onload_callbacks.forEach(function(callback) {\n", + " if (callback != null)\n", + " callback();\n", + " });\n", + " } finally {\n", + " delete root._bokeh_onload_callbacks\n", + " }\n", + " console.debug(\"Bokeh: all callbacks have finished\");\n", + " }\n", + "\n", + " function load_libs(css_urls, js_urls, callback) {\n", + " if (css_urls == null) css_urls = [];\n", + " if (js_urls == null) js_urls = [];\n", + "\n", + " root._bokeh_onload_callbacks.push(callback);\n", + " if (root._bokeh_is_loading > 0) {\n", + " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", + " return null;\n", + " }\n", + " if (js_urls == null || js_urls.length === 0) {\n", + " run_callbacks();\n", + " return null;\n", + " }\n", + " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", + " root._bokeh_is_loading = css_urls.length + js_urls.length;\n", + "\n", + " function on_load() {\n", + " root._bokeh_is_loading--;\n", + " if (root._bokeh_is_loading === 0) {\n", + " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", + " run_callbacks()\n", + " }\n", + " }\n", + "\n", + " function on_error() {\n", + " console.error(\"failed to load \" + url);\n", + " }\n", + "\n", + " for (var i = 0; i < css_urls.length; i++) {\n", + " var url = css_urls[i];\n", + " const element = document.createElement(\"link\");\n", + " element.onload = on_load;\n", + " element.onerror = on_error;\n", + " element.rel = \"stylesheet\";\n", + " element.type = \"text/css\";\n", + " element.href = url;\n", + " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", + " document.body.appendChild(element);\n", + " }\n", + "\n", + " for (var i = 0; i < js_urls.length; i++) {\n", + " var url = js_urls[i];\n", + " var element = document.createElement('script');\n", + " element.onload = on_load;\n", + " element.onerror = on_error;\n", + " element.async = false;\n", + " element.src = url;\n", + " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", + " document.head.appendChild(element);\n", + " }\n", + " };var element = document.getElementById(\"1246\");\n", + " if (element == null) {\n", + " console.error(\"Bokeh: ERROR: autoload.js configured with elementid '1246' but no matching script tag was found. \")\n", + " return false;\n", + " }\n", + "\n", + " function inject_raw_css(css) {\n", + " const element = document.createElement(\"style\");\n", + " element.appendChild(document.createTextNode(css));\n", + " document.body.appendChild(element);\n", + " }\n", + "\n", + " var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.1.0.min.js\"];\n", + " var css_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.css\"];\n", + "\n", + " var inline_js = [\n", + " function(Bokeh) {\n", + " Bokeh.set_log_level(\"info\");\n", + " },\n", + " \n", + " function(Bokeh) {\n", + " (function(root, factory) {\n", + " // if(typeof exports === 'object' && typeof module === 'object')\n", + " // factory(require(\"Bokeh\"));\n", + " // else if(typeof define === 'function' && define.amd)\n", + " // define([\"Bokeh\"], factory);\n", + " // else if(typeof exports === 'object')\n", + " // factory(require(\"Bokeh\"));\n", + " // else\n", + " factory(root[\"Bokeh\"]);\n", + " })(this, function(Bokeh) {\n", + " var define;\n", + " return (function outer(modules, entry) {\n", + " if (Bokeh != null) {\n", + " return Bokeh.register_plugin(modules, {}, entry);\n", + " } else {\n", + " throw new Error(\"Cannot find Bokeh. You have to load it prior to loading plugins.\");\n", + " }\n", + " })\n", + " ({\n", + " \"custom/main\": function(require, module, exports) {\n", + " var models = {\n", + " \"ParallelResetTool\": require(\"custom/cave.plot.parallel_plot.parallel_reset.parallel_reset_tool\").ParallelResetTool,\n", + " \"ParallelSelectionTool\": require(\"custom/cave.plot.parallel_plot.parallel_selection_tool.parallel_selection_tool\").ParallelSelectionTool\n", + " };\n", + " require(\"base\").register_models(models);\n", + " module.exports = models;\n", + " },\n", + " \"custom/cave.plot.parallel_plot.parallel_reset.parallel_reset_tool\": function(require, module, exports) {\n", + " \"use strict\";\n", + " var __extends = (this && this.__extends) || (function () {\n", + " var extendStatics = function (d, b) {\n", + " extendStatics = Object.setPrototypeOf ||\n", + " ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n", + " function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n", + " return extendStatics(d, b);\n", + " };\n", + " return function (d, b) {\n", + " extendStatics(d, b);\n", + " function __() { this.constructor = d; }\n", + " d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n", + " };\n", + " })();\n", + " Object.defineProperty(exports, \"__esModule\", { value: true });\n", + " var action_tool_1 = require(\"models/tools/actions/action_tool\");\n", + " var ParallelResetToolView = /** @class */ (function (_super) {\n", + " __extends(ParallelResetToolView, _super);\n", + " function ParallelResetToolView() {\n", + " return _super !== null && _super.apply(this, arguments) || this;\n", + " }\n", + " ParallelResetToolView.prototype.doit = function () {\n", + " this.plot_view.reset_range();\n", + " };\n", + " return ParallelResetToolView;\n", + " }(action_tool_1.ActionToolView));\n", + " exports.ParallelResetToolView = ParallelResetToolView;\n", + " var ParallelResetTool = /** @class */ (function (_super) {\n", + " __extends(ParallelResetTool, _super);\n", + " function ParallelResetTool(attrs) {\n", + " var _this = _super.call(this, attrs) || this;\n", + " _this.tool_name = \"Reset Zoom\";\n", + " _this.icon = \"bk-tool-icon-reset\";\n", + " return _this;\n", + " }\n", + " ParallelResetTool.initClass = function () {\n", + " this.prototype.type = \"ParallelResetTool\";\n", + " this.prototype.default_view = ParallelResetToolView;\n", + " };\n", + " return ParallelResetTool;\n", + " }(action_tool_1.ActionTool));\n", + " exports.ParallelResetTool = ParallelResetTool;\n", + " ParallelResetTool.initClass();\n", + "\n", + " },\n", + " \"custom/cave.plot.parallel_plot.parallel_selection_tool.parallel_selection_tool\": function(require, module, exports) {\n", + " \"use strict\";\n", + " var __extends = (this && this.__extends) || (function () {\n", + " var extendStatics = function (d, b) {\n", + " extendStatics = Object.setPrototypeOf ||\n", + " ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n", + " function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n", + " return extendStatics(d, b);\n", + " };\n", + " return function (d, b) {\n", + " extendStatics(d, b);\n", + " function __() { this.constructor = d; }\n", + " d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n", + " };\n", + " })();\n", + " Object.defineProperty(exports, \"__esModule\", { value: true });\n", + " var p = require(\"core/properties\");\n", + " var box_select_tool_1 = require(\"models/tools/gestures/box_select_tool\");\n", + " var array_1 = require(\"core/util/array\");\n", + " var dom_1 = require(\"core/dom\");\n", + " function find_indices_in(array, _a) {\n", + " var inf = _a[0], sup = _a[1];\n", + " return array.reduce(function (prev, curr, index) {\n", + " return (inf <= curr && curr <= sup) ? prev.concat(index) : prev;\n", + " }, []);\n", + " }\n", + " function index_array(array, indices) {\n", + " return indices.reduce(function (a, i) { return a.concat(array[i]); }, []);\n", + " }\n", + " function combineByKey(key, array) {\n", + " var keys = Object.keys(array[0]);\n", + " var combined = [];\n", + " array.forEach(function (itm) {\n", + " var idx = combined.map(function (item) { return item[key]; }).indexOf(itm[key]);\n", + " if (idx >= 0) {\n", + " keys.forEach(function (element) {\n", + " if (element != key)\n", + " combined[idx][element].push(itm[element]);\n", + " });\n", + " }\n", + " else {\n", + " var new_object_1 = {};\n", + " keys.forEach(function (element) {\n", + " if (element == key) {\n", + " new_object_1[element] = itm[element];\n", + " }\n", + " else {\n", + " new_object_1[element] = [itm[element]];\n", + " }\n", + " });\n", + " combined.push(new_object_1);\n", + " }\n", + " });\n", + " return combined;\n", + " }\n", + " var ParallelSelectionView = /** @class */ (function (_super) {\n", + " __extends(ParallelSelectionView, _super);\n", + " function ParallelSelectionView() {\n", + " var _this = _super !== null && _super.apply(this, arguments) || this;\n", + " _this.selection_mode = \"add\";\n", + " _this.panning = false;\n", + " return _this;\n", + " }\n", + " ParallelSelectionView.prototype.initialize = function () {\n", + " var _this = this;\n", + " _super.prototype.initialize.call(this);\n", + " var frame = this.plot_view.frame;\n", + " var _a = this.model.renderer_select, x_range_name_select = _a.x_range_name, y_range_name_select = _a.y_range_name;\n", + " var _b = this.model.renderer_data, x_range_name_data = _b.x_range_name, y_range_name_data = _b.y_range_name;\n", + " if (x_range_name_select == x_range_name_data && y_range_name_select == y_range_name_data) {\n", + " this.xscale = frame.xscales[x_range_name_select];\n", + " this.yscale = frame.yscales[y_range_name_select];\n", + " }\n", + " else\n", + " throw new Error(\"selection and data does not share the same ranges\");\n", + " //TODO test if parallel CDS is valid (xs for each line should be identical)\n", + " this.glyph_select = this.model.renderer_select.glyph;\n", + " this.glyph_data = this.model.renderer_data.glyph;\n", + " this.cds_select = this.model.renderer_select.data_source;\n", + " this.cds_data = this.model.renderer_data.data_source;\n", + " var _c = [this.glyph_data.xs.field, this.glyph_data.ys.field], xskey = _c[0], yskey = _c[1];\n", + " this.xdata = this.cds_data.get_array(xskey)[0];\n", + " this.ydataT = array_1.transpose(this.cds_data.get_array(yskey));\n", + " this.selection_indices = [];\n", + " this.connect(this.plot_view.frame.x_ranges[this.model.renderer_select.x_range_name].change, function () { return _this._resize_boxes_on_zoom(); });\n", + " this.connect(this.cds_select.change, function () { return _this._update_data_selection(); });\n", + " };\n", + " Object.defineProperty(ParallelSelectionView.prototype, \"_box_width\", {\n", + " get: function () {\n", + " return this.xscale.invert(this.model.box_width) - this.xscale.invert(0);\n", + " },\n", + " enumerable: true,\n", + " configurable: true\n", + " });\n", + " Object.defineProperty(ParallelSelectionView.prototype, \"_cds_select_keys\", {\n", + " get: function () {\n", + " var glyph_select = this.glyph_select;\n", + " var _a = [glyph_select.x.field, glyph_select.y.field], xkey = _a[0], ykey = _a[1];\n", + " var _b = [glyph_select.width.field, glyph_select.height.field], wkey = _b[0], hkey = _b[1];\n", + " return { xkey: xkey, ykey: ykey, wkey: wkey, hkey: hkey };\n", + " },\n", + " enumerable: true,\n", + " configurable: true\n", + " });\n", + " ParallelSelectionView.prototype._emit_cds_changes = function (cds, redraw, clear, emit) {\n", + " if (redraw === void 0) { redraw = true; }\n", + " if (clear === void 0) { clear = true; }\n", + " if (emit === void 0) { emit = true; }\n", + " if (clear)\n", + " cds.selection_manager.clear();\n", + " if (redraw)\n", + " cds.change.emit();\n", + " if (emit) {\n", + " cds.data = cds.data;\n", + " cds.properties.data.change.emit();\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._box_paramaters = function (index) {\n", + " var _a = this._cds_select_keys, xkey = _a.xkey, ykey = _a.ykey, wkey = _a.wkey, hkey = _a.hkey;\n", + " var x = this.cds_select.get_array(xkey)[index];\n", + " var y = this.cds_select.get_array(ykey)[index];\n", + " var w = this.cds_select.get_array(wkey)[index];\n", + " var h = this.cds_select.get_array(hkey)[index];\n", + " return { x: x, y: y, w: w, h: h };\n", + " };\n", + " ParallelSelectionView.prototype._hit_test_boxes = function (sx, sy) {\n", + " var nboxes = this.cds_select.get_length();\n", + " if (nboxes != 0 && nboxes != null) {\n", + " var _a = [this.xscale.invert(sx), this.yscale.invert(sy)], xtest = _a[0], ytest = _a[1];\n", + " for (var i = 0; i < nboxes; i++) {\n", + " var _b = this._box_paramaters(i), x = _b.x, y = _b.y, w = _b.w, h = _b.h;\n", + " if (xtest >= (x - w / 2) && xtest <= x + w / 2 &&\n", + " ytest >= (y - h / 2) && ytest <= y + h / 2) {\n", + " return i;\n", + " }\n", + " }\n", + " }\n", + " return null;\n", + " };\n", + " ParallelSelectionView.prototype._resize_boxes_on_zoom = function () {\n", + " //resize selection boxes when zooming to keep a constant (pixel) size\n", + " var cds = this.cds_select;\n", + " var array_width = cds.get_array(this.glyph_select.width.field);\n", + " var new_width = this._box_width;\n", + " array_width.forEach(function (_, i) { return array_width[i] = new_width; });\n", + " this._emit_cds_changes(cds, true, false, false);\n", + " };\n", + " ParallelSelectionView.prototype._drag_start = function (ev) {\n", + " //Save y position of the drag start\n", + " if (this.ind_active_box != null) {\n", + " this._base_point = [this.xscale.invert(ev.sx), this.yscale.invert(ev.sy)];\n", + " this._base_box_parameters = this._box_paramaters(this.ind_active_box);\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._update_box_ypos = function (index_box, delta_y) {\n", + " if (this._base_box_parameters != null) {\n", + " var cds = this.cds_select;\n", + " var ykey = this._cds_select_keys.ykey;\n", + " var _a = this._base_box_parameters, current_y = _a.y, h = _a.h;\n", + " var new_y = current_y + delta_y;\n", + " new_y = new_y - Math.max(0, (new_y + h / 2) - 1) - Math.min(0, (new_y - h / 2));\n", + " cds.get_array(ykey)[index_box] = new_y;\n", + " this._emit_cds_changes(cds, true, false, false);\n", + " this._update_selection_indices(index_box, [new_y - h / 2, new_y + h / 2]);\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._drag = function (ev) {\n", + " if (this.ind_active_box != null && this._base_point != null) {\n", + " var delta_y = this.yscale.invert(ev.sy) - this._base_point[1];\n", + " this._update_box_ypos(this.ind_active_box, delta_y);\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._drag_stop = function (_ev) {\n", + " this._base_point = null;\n", + " this._base_box_parameters = null;\n", + " };\n", + " ParallelSelectionView.prototype._pan_start = function (ev) {\n", + " this.panning = true;\n", + " switch (this.selection_mode) {\n", + " case \"add\": {\n", + " _super.prototype._pan_start.call(this, ev);\n", + " break;\n", + " }\n", + " case \"drag\": {\n", + " this._drag_start(ev);\n", + " break;\n", + " }\n", + " case \"resize\": {\n", + " break;\n", + " }\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._pan = function (ev) {\n", + " switch (this.selection_mode) {\n", + " case \"add\": {\n", + " _super.prototype._pan.call(this, ev);\n", + " break;\n", + " }\n", + " case \"drag\": {\n", + " this._drag(ev);\n", + " break;\n", + " }\n", + " case \"resize\": {\n", + " break;\n", + " }\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._pan_end = function (ev) {\n", + " switch (this.selection_mode) {\n", + " case \"add\": {\n", + " _super.prototype._pan_end.call(this, ev);\n", + " break;\n", + " }\n", + " case \"drag\": {\n", + " this._drag_stop(ev);\n", + " break;\n", + " }\n", + " case \"resize\": {\n", + " break;\n", + " }\n", + " }\n", + " this.panning = false;\n", + " };\n", + " ParallelSelectionView.prototype._move = function (ev) {\n", + " //Switch mode\n", + " if (this.panning) {\n", + " return;\n", + " }\n", + " this.ind_active_box = this._hit_test_boxes(ev.sx, ev.sy);\n", + " if (this.ind_active_box != null) {\n", + " this.selection_mode = \"drag\";\n", + " }\n", + " else {\n", + " this.selection_mode = \"add\";\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._doubletap = function (_ev) {\n", + " var _this = this;\n", + " //delete box on double tap\n", + " if (this.ind_active_box != null) {\n", + " this.cds_select.columns().forEach(function (key) {\n", + " _this.cds_select.get_array(key).splice(_this.ind_active_box, 1);\n", + " });\n", + " this._delete_selection_indices(this.ind_active_box);\n", + " this._emit_cds_changes(this.cds_select);\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._keyup = function (ev) {\n", + " var _this = this;\n", + " if (ev.keyCode == dom_1.Keys.Esc) {\n", + " var nelems_1 = this.cds_select.get_length();\n", + " if (nelems_1 != null) {\n", + " this.cds_select.columns().forEach(function (key) {\n", + " _this.cds_select.get_array(key).splice(0, nelems_1);\n", + " });\n", + " this.selection_indices.splice(0, nelems_1);\n", + " this._emit_cds_changes(this.cds_select);\n", + " }\n", + " this.plot_view.request_render();\n", + " }\n", + " };\n", + " ParallelSelectionView.prototype._update_data_selection = function () {\n", + " var selection_indices = [];\n", + " if (this.selection_indices.length > 0) {\n", + " var combined_selections = combineByKey('data_idx', this.selection_indices);\n", + " selection_indices = array_1.intersection.apply(void 0, [array_1.union.apply(void 0, combined_selections[0].indices)].concat(combined_selections.slice(1).map(function (elem) { return array_1.union.apply(void 0, elem.indices); })));\n", + " }\n", + " this.cds_data.selected.indices = selection_indices;\n", + " this.cds_data.change.emit();\n", + " };\n", + " ParallelSelectionView.prototype._make_selection_indices = function (indices, _a) {\n", + " var _this = this;\n", + " var _b;\n", + " var y0 = _a[0], y1 = _a[1];\n", + " (_b = this.selection_indices).push.apply(_b, indices.map(function (index) {\n", + " return {\n", + " data_idx: index,\n", + " indices: find_indices_in(_this.ydataT[index], [y0, y1]),\n", + " };\n", + " }));\n", + " };\n", + " ParallelSelectionView.prototype._update_selection_indices = function (index, _a) {\n", + " var y0 = _a[0], y1 = _a[1];\n", + " this.selection_indices[index].indices = find_indices_in(this.ydataT[this.selection_indices[index].data_idx], [y0, y1]);\n", + " };\n", + " ParallelSelectionView.prototype._delete_selection_indices = function (index) {\n", + " this.selection_indices.splice(index, 1);\n", + " };\n", + " ParallelSelectionView.prototype._make_box_select = function (xs, _a) {\n", + " var _this = this;\n", + " var y0 = _a[0], y1 = _a[1];\n", + " y0 = Math.max(0, y0);\n", + " y1 = Math.min(1, y1);\n", + " var y = (y0 + y1) / 2.;\n", + " var w = this._box_width;\n", + " var h = y1 - y0;\n", + " var _b = this._cds_select_keys, xkey = _b.xkey, ykey = _b.ykey, wkey = _b.wkey, hkey = _b.hkey;\n", + " xs.forEach(function (x) {\n", + " if (xkey)\n", + " _this.cds_select.get_array(xkey).push(x);\n", + " if (ykey)\n", + " _this.cds_select.get_array(ykey).push(y);\n", + " if (wkey)\n", + " _this.cds_select.get_array(wkey).push(w);\n", + " if (hkey)\n", + " _this.cds_select.get_array(hkey).push(h);\n", + " });\n", + " this._emit_cds_changes(this.cds_select);\n", + " };\n", + " ParallelSelectionView.prototype._do_select = function (_a, _b, _final, _append) {\n", + " var sx0 = _a[0], sx1 = _a[1];\n", + " var sy0 = _b[0], sy1 = _b[1];\n", + " if (_final === void 0) { _final = true; }\n", + " if (_append === void 0) { _append = true; }\n", + " // Get selection bbox in the data space\n", + " var _c = this.xscale.r_invert(sx0, sx1), x0 = _c[0], x1 = _c[1];\n", + " var _d = this.yscale.r_invert(sy0, sy1), y0 = _d[0], y1 = _d[1];\n", + " var x_indices = find_indices_in(this.xdata, [x0, x1]);\n", + " var xs = index_array(this.xdata, x_indices);\n", + " this._make_selection_indices(x_indices, [y0, y1]);\n", + " this._make_box_select(xs, [y0, y1]);\n", + " };\n", + " return ParallelSelectionView;\n", + " }(box_select_tool_1.BoxSelectToolView));\n", + " exports.ParallelSelectionView = ParallelSelectionView;\n", + " var ParallelSelectionTool = /** @class */ (function (_super) {\n", + " __extends(ParallelSelectionTool, _super);\n", + " function ParallelSelectionTool() {\n", + " var _this = _super !== null && _super.apply(this, arguments) || this;\n", + " _this.tool_name = \"Parallel Selection\";\n", + " //override event_type property define in BoxSelectTool\n", + " _this.event_type = [\"tap\", \"pan\", \"move\"];\n", + " return _this;\n", + " }\n", + " ParallelSelectionTool.initClass = function () {\n", + " this.prototype.type = \"ParallelSelectionTool\";\n", + " this.prototype.default_view = ParallelSelectionView;\n", + " this.define({\n", + " renderer_select: [p.Any],\n", + " renderer_data: [p.Any],\n", + " box_width: [p.Number, 30],\n", + " });\n", + " };\n", + " return ParallelSelectionTool;\n", + " }(box_select_tool_1.BoxSelectTool));\n", + " exports.ParallelSelectionTool = ParallelSelectionTool;\n", + " ParallelSelectionTool.initClass();\n", + "\n", + " }\n", + " }, \"custom/main\");\n", + " ;\n", + " });\n", + "\n", + " },\n", + " function(Bokeh) {} // ensure no trailing comma for IE\n", + " ];\n", + "\n", + " function run_inline_js() {\n", + " \n", + " if ((root.Bokeh !== undefined) || (force === true)) {\n", + " for (var i = 0; i < inline_js.length; i++) {\n", + " inline_js[i].call(root, root.Bokeh);\n", + " }if (force === true) {\n", + " display_loaded();\n", + " }} else if (Date.now() < root._bokeh_timeout) {\n", + " setTimeout(run_inline_js, 100);\n", + " } else if (!root._bokeh_failed_load) {\n", + " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", + " root._bokeh_failed_load = true;\n", + " } else if (force !== true) {\n", + " var cell = $(document.getElementById(\"1246\")).parents('.cell').data().cell;\n", + " cell.output_area.append_execute_result(NB_LOAD_WARNING)\n", + " }\n", + "\n", + " }\n", + "\n", + " if (root._bokeh_is_loading === 0) {\n", + " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", + " run_inline_js();\n", + " } else {\n", + " load_libs(css_urls, js_urls, function() {\n", + " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", + " run_inline_js();\n", + " });\n", + " }\n", + "}(window));" + ], + "application/vnd.bokehjs_load.v0+json": "\n(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n \n\n \n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n var NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n var el = document.getElementById(\"1246\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };var element = document.getElementById(\"1246\");\n if (element == null) {\n console.error(\"Bokeh: ERROR: autoload.js configured with elementid '1246' but no matching script tag was found. \")\n return false;\n }\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.1.0.min.js\"];\n var css_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.css\"];\n\n var inline_js = [\n function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n \n function(Bokeh) {\n (function(root, factory) {\n // if(typeof exports === 'object' && typeof module === 'object')\n // factory(require(\"Bokeh\"));\n // else if(typeof define === 'function' && define.amd)\n // define([\"Bokeh\"], factory);\n // else if(typeof exports === 'object')\n // factory(require(\"Bokeh\"));\n // else\n factory(root[\"Bokeh\"]);\n })(this, function(Bokeh) {\n var define;\n return (function outer(modules, entry) {\n if (Bokeh != null) {\n return Bokeh.register_plugin(modules, {}, entry);\n } else {\n throw new Error(\"Cannot find Bokeh. You have to load it prior to loading plugins.\");\n }\n })\n ({\n \"custom/main\": function(require, module, exports) {\n var models = {\n \"ParallelResetTool\": require(\"custom/cave.plot.parallel_plot.parallel_reset.parallel_reset_tool\").ParallelResetTool,\n \"ParallelSelectionTool\": require(\"custom/cave.plot.parallel_plot.parallel_selection_tool.parallel_selection_tool\").ParallelSelectionTool\n };\n require(\"base\").register_models(models);\n module.exports = models;\n },\n \"custom/cave.plot.parallel_plot.parallel_reset.parallel_reset_tool\": function(require, module, exports) {\n \"use strict\";\n var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n })();\n Object.defineProperty(exports, \"__esModule\", { value: true });\n var action_tool_1 = require(\"models/tools/actions/action_tool\");\n var ParallelResetToolView = /** @class */ (function (_super) {\n __extends(ParallelResetToolView, _super);\n function ParallelResetToolView() {\n return _super !== null && _super.apply(this, arguments) || this;\n }\n ParallelResetToolView.prototype.doit = function () {\n this.plot_view.reset_range();\n };\n return ParallelResetToolView;\n }(action_tool_1.ActionToolView));\n exports.ParallelResetToolView = ParallelResetToolView;\n var ParallelResetTool = /** @class */ (function (_super) {\n __extends(ParallelResetTool, _super);\n function ParallelResetTool(attrs) {\n var _this = _super.call(this, attrs) || this;\n _this.tool_name = \"Reset Zoom\";\n _this.icon = \"bk-tool-icon-reset\";\n return _this;\n }\n ParallelResetTool.initClass = function () {\n this.prototype.type = \"ParallelResetTool\";\n this.prototype.default_view = ParallelResetToolView;\n };\n return ParallelResetTool;\n }(action_tool_1.ActionTool));\n exports.ParallelResetTool = ParallelResetTool;\n ParallelResetTool.initClass();\n\n },\n \"custom/cave.plot.parallel_plot.parallel_selection_tool.parallel_selection_tool\": function(require, module, exports) {\n \"use strict\";\n var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n })();\n Object.defineProperty(exports, \"__esModule\", { value: true });\n var p = require(\"core/properties\");\n var box_select_tool_1 = require(\"models/tools/gestures/box_select_tool\");\n var array_1 = require(\"core/util/array\");\n var dom_1 = require(\"core/dom\");\n function find_indices_in(array, _a) {\n var inf = _a[0], sup = _a[1];\n return array.reduce(function (prev, curr, index) {\n return (inf <= curr && curr <= sup) ? prev.concat(index) : prev;\n }, []);\n }\n function index_array(array, indices) {\n return indices.reduce(function (a, i) { return a.concat(array[i]); }, []);\n }\n function combineByKey(key, array) {\n var keys = Object.keys(array[0]);\n var combined = [];\n array.forEach(function (itm) {\n var idx = combined.map(function (item) { return item[key]; }).indexOf(itm[key]);\n if (idx >= 0) {\n keys.forEach(function (element) {\n if (element != key)\n combined[idx][element].push(itm[element]);\n });\n }\n else {\n var new_object_1 = {};\n keys.forEach(function (element) {\n if (element == key) {\n new_object_1[element] = itm[element];\n }\n else {\n new_object_1[element] = [itm[element]];\n }\n });\n combined.push(new_object_1);\n }\n });\n return combined;\n }\n var ParallelSelectionView = /** @class */ (function (_super) {\n __extends(ParallelSelectionView, _super);\n function ParallelSelectionView() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n _this.selection_mode = \"add\";\n _this.panning = false;\n return _this;\n }\n ParallelSelectionView.prototype.initialize = function () {\n var _this = this;\n _super.prototype.initialize.call(this);\n var frame = this.plot_view.frame;\n var _a = this.model.renderer_select, x_range_name_select = _a.x_range_name, y_range_name_select = _a.y_range_name;\n var _b = this.model.renderer_data, x_range_name_data = _b.x_range_name, y_range_name_data = _b.y_range_name;\n if (x_range_name_select == x_range_name_data && y_range_name_select == y_range_name_data) {\n this.xscale = frame.xscales[x_range_name_select];\n this.yscale = frame.yscales[y_range_name_select];\n }\n else\n throw new Error(\"selection and data does not share the same ranges\");\n //TODO test if parallel CDS is valid (xs for each line should be identical)\n this.glyph_select = this.model.renderer_select.glyph;\n this.glyph_data = this.model.renderer_data.glyph;\n this.cds_select = this.model.renderer_select.data_source;\n this.cds_data = this.model.renderer_data.data_source;\n var _c = [this.glyph_data.xs.field, this.glyph_data.ys.field], xskey = _c[0], yskey = _c[1];\n this.xdata = this.cds_data.get_array(xskey)[0];\n this.ydataT = array_1.transpose(this.cds_data.get_array(yskey));\n this.selection_indices = [];\n this.connect(this.plot_view.frame.x_ranges[this.model.renderer_select.x_range_name].change, function () { return _this._resize_boxes_on_zoom(); });\n this.connect(this.cds_select.change, function () { return _this._update_data_selection(); });\n };\n Object.defineProperty(ParallelSelectionView.prototype, \"_box_width\", {\n get: function () {\n return this.xscale.invert(this.model.box_width) - this.xscale.invert(0);\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(ParallelSelectionView.prototype, \"_cds_select_keys\", {\n get: function () {\n var glyph_select = this.glyph_select;\n var _a = [glyph_select.x.field, glyph_select.y.field], xkey = _a[0], ykey = _a[1];\n var _b = [glyph_select.width.field, glyph_select.height.field], wkey = _b[0], hkey = _b[1];\n return { xkey: xkey, ykey: ykey, wkey: wkey, hkey: hkey };\n },\n enumerable: true,\n configurable: true\n });\n ParallelSelectionView.prototype._emit_cds_changes = function (cds, redraw, clear, emit) {\n if (redraw === void 0) { redraw = true; }\n if (clear === void 0) { clear = true; }\n if (emit === void 0) { emit = true; }\n if (clear)\n cds.selection_manager.clear();\n if (redraw)\n cds.change.emit();\n if (emit) {\n cds.data = cds.data;\n cds.properties.data.change.emit();\n }\n };\n ParallelSelectionView.prototype._box_paramaters = function (index) {\n var _a = this._cds_select_keys, xkey = _a.xkey, ykey = _a.ykey, wkey = _a.wkey, hkey = _a.hkey;\n var x = this.cds_select.get_array(xkey)[index];\n var y = this.cds_select.get_array(ykey)[index];\n var w = this.cds_select.get_array(wkey)[index];\n var h = this.cds_select.get_array(hkey)[index];\n return { x: x, y: y, w: w, h: h };\n };\n ParallelSelectionView.prototype._hit_test_boxes = function (sx, sy) {\n var nboxes = this.cds_select.get_length();\n if (nboxes != 0 && nboxes != null) {\n var _a = [this.xscale.invert(sx), this.yscale.invert(sy)], xtest = _a[0], ytest = _a[1];\n for (var i = 0; i < nboxes; i++) {\n var _b = this._box_paramaters(i), x = _b.x, y = _b.y, w = _b.w, h = _b.h;\n if (xtest >= (x - w / 2) && xtest <= x + w / 2 &&\n ytest >= (y - h / 2) && ytest <= y + h / 2) {\n return i;\n }\n }\n }\n return null;\n };\n ParallelSelectionView.prototype._resize_boxes_on_zoom = function () {\n //resize selection boxes when zooming to keep a constant (pixel) size\n var cds = this.cds_select;\n var array_width = cds.get_array(this.glyph_select.width.field);\n var new_width = this._box_width;\n array_width.forEach(function (_, i) { return array_width[i] = new_width; });\n this._emit_cds_changes(cds, true, false, false);\n };\n ParallelSelectionView.prototype._drag_start = function (ev) {\n //Save y position of the drag start\n if (this.ind_active_box != null) {\n this._base_point = [this.xscale.invert(ev.sx), this.yscale.invert(ev.sy)];\n this._base_box_parameters = this._box_paramaters(this.ind_active_box);\n }\n };\n ParallelSelectionView.prototype._update_box_ypos = function (index_box, delta_y) {\n if (this._base_box_parameters != null) {\n var cds = this.cds_select;\n var ykey = this._cds_select_keys.ykey;\n var _a = this._base_box_parameters, current_y = _a.y, h = _a.h;\n var new_y = current_y + delta_y;\n new_y = new_y - Math.max(0, (new_y + h / 2) - 1) - Math.min(0, (new_y - h / 2));\n cds.get_array(ykey)[index_box] = new_y;\n this._emit_cds_changes(cds, true, false, false);\n this._update_selection_indices(index_box, [new_y - h / 2, new_y + h / 2]);\n }\n };\n ParallelSelectionView.prototype._drag = function (ev) {\n if (this.ind_active_box != null && this._base_point != null) {\n var delta_y = this.yscale.invert(ev.sy) - this._base_point[1];\n this._update_box_ypos(this.ind_active_box, delta_y);\n }\n };\n ParallelSelectionView.prototype._drag_stop = function (_ev) {\n this._base_point = null;\n this._base_box_parameters = null;\n };\n ParallelSelectionView.prototype._pan_start = function (ev) {\n this.panning = true;\n switch (this.selection_mode) {\n case \"add\": {\n _super.prototype._pan_start.call(this, ev);\n break;\n }\n case \"drag\": {\n this._drag_start(ev);\n break;\n }\n case \"resize\": {\n break;\n }\n }\n };\n ParallelSelectionView.prototype._pan = function (ev) {\n switch (this.selection_mode) {\n case \"add\": {\n _super.prototype._pan.call(this, ev);\n break;\n }\n case \"drag\": {\n this._drag(ev);\n break;\n }\n case \"resize\": {\n break;\n }\n }\n };\n ParallelSelectionView.prototype._pan_end = function (ev) {\n switch (this.selection_mode) {\n case \"add\": {\n _super.prototype._pan_end.call(this, ev);\n break;\n }\n case \"drag\": {\n this._drag_stop(ev);\n break;\n }\n case \"resize\": {\n break;\n }\n }\n this.panning = false;\n };\n ParallelSelectionView.prototype._move = function (ev) {\n //Switch mode\n if (this.panning) {\n return;\n }\n this.ind_active_box = this._hit_test_boxes(ev.sx, ev.sy);\n if (this.ind_active_box != null) {\n this.selection_mode = \"drag\";\n }\n else {\n this.selection_mode = \"add\";\n }\n };\n ParallelSelectionView.prototype._doubletap = function (_ev) {\n var _this = this;\n //delete box on double tap\n if (this.ind_active_box != null) {\n this.cds_select.columns().forEach(function (key) {\n _this.cds_select.get_array(key).splice(_this.ind_active_box, 1);\n });\n this._delete_selection_indices(this.ind_active_box);\n this._emit_cds_changes(this.cds_select);\n }\n };\n ParallelSelectionView.prototype._keyup = function (ev) {\n var _this = this;\n if (ev.keyCode == dom_1.Keys.Esc) {\n var nelems_1 = this.cds_select.get_length();\n if (nelems_1 != null) {\n this.cds_select.columns().forEach(function (key) {\n _this.cds_select.get_array(key).splice(0, nelems_1);\n });\n this.selection_indices.splice(0, nelems_1);\n this._emit_cds_changes(this.cds_select);\n }\n this.plot_view.request_render();\n }\n };\n ParallelSelectionView.prototype._update_data_selection = function () {\n var selection_indices = [];\n if (this.selection_indices.length > 0) {\n var combined_selections = combineByKey('data_idx', this.selection_indices);\n selection_indices = array_1.intersection.apply(void 0, [array_1.union.apply(void 0, combined_selections[0].indices)].concat(combined_selections.slice(1).map(function (elem) { return array_1.union.apply(void 0, elem.indices); })));\n }\n this.cds_data.selected.indices = selection_indices;\n this.cds_data.change.emit();\n };\n ParallelSelectionView.prototype._make_selection_indices = function (indices, _a) {\n var _this = this;\n var _b;\n var y0 = _a[0], y1 = _a[1];\n (_b = this.selection_indices).push.apply(_b, indices.map(function (index) {\n return {\n data_idx: index,\n indices: find_indices_in(_this.ydataT[index], [y0, y1]),\n };\n }));\n };\n ParallelSelectionView.prototype._update_selection_indices = function (index, _a) {\n var y0 = _a[0], y1 = _a[1];\n this.selection_indices[index].indices = find_indices_in(this.ydataT[this.selection_indices[index].data_idx], [y0, y1]);\n };\n ParallelSelectionView.prototype._delete_selection_indices = function (index) {\n this.selection_indices.splice(index, 1);\n };\n ParallelSelectionView.prototype._make_box_select = function (xs, _a) {\n var _this = this;\n var y0 = _a[0], y1 = _a[1];\n y0 = Math.max(0, y0);\n y1 = Math.min(1, y1);\n var y = (y0 + y1) / 2.;\n var w = this._box_width;\n var h = y1 - y0;\n var _b = this._cds_select_keys, xkey = _b.xkey, ykey = _b.ykey, wkey = _b.wkey, hkey = _b.hkey;\n xs.forEach(function (x) {\n if (xkey)\n _this.cds_select.get_array(xkey).push(x);\n if (ykey)\n _this.cds_select.get_array(ykey).push(y);\n if (wkey)\n _this.cds_select.get_array(wkey).push(w);\n if (hkey)\n _this.cds_select.get_array(hkey).push(h);\n });\n this._emit_cds_changes(this.cds_select);\n };\n ParallelSelectionView.prototype._do_select = function (_a, _b, _final, _append) {\n var sx0 = _a[0], sx1 = _a[1];\n var sy0 = _b[0], sy1 = _b[1];\n if (_final === void 0) { _final = true; }\n if (_append === void 0) { _append = true; }\n // Get selection bbox in the data space\n var _c = this.xscale.r_invert(sx0, sx1), x0 = _c[0], x1 = _c[1];\n var _d = this.yscale.r_invert(sy0, sy1), y0 = _d[0], y1 = _d[1];\n var x_indices = find_indices_in(this.xdata, [x0, x1]);\n var xs = index_array(this.xdata, x_indices);\n this._make_selection_indices(x_indices, [y0, y1]);\n this._make_box_select(xs, [y0, y1]);\n };\n return ParallelSelectionView;\n }(box_select_tool_1.BoxSelectToolView));\n exports.ParallelSelectionView = ParallelSelectionView;\n var ParallelSelectionTool = /** @class */ (function (_super) {\n __extends(ParallelSelectionTool, _super);\n function ParallelSelectionTool() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n _this.tool_name = \"Parallel Selection\";\n //override event_type property define in BoxSelectTool\n _this.event_type = [\"tap\", \"pan\", \"move\"];\n return _this;\n }\n ParallelSelectionTool.initClass = function () {\n this.prototype.type = \"ParallelSelectionTool\";\n this.prototype.default_view = ParallelSelectionView;\n this.define({\n renderer_select: [p.Any],\n renderer_data: [p.Any],\n box_width: [p.Number, 30],\n });\n };\n return ParallelSelectionTool;\n }(box_select_tool_1.BoxSelectTool));\n exports.ParallelSelectionTool = ParallelSelectionTool;\n ParallelSelectionTool.initClass();\n\n }\n }, \"custom/main\");\n ;\n });\n\n },\n function(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n \n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }if (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n var cell = $(document.getElementById(\"1246\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "ename": "ValueError", + "evalue": "\"Invalid object to show. The object to passed to show must be one of:\n\n* a LayoutDOM (e.g. a Plot or Widget or Layout)\n* a Bokeh Application\n* a callable suitable to an application FunctionHandler\n", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mcave\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpimp_forward_selection\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m~/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/cave/cavefacade.py\u001b[0m in \u001b[0;36mwrap\u001b[0;34m(self, d, *args, **kw)\u001b[0m\n\u001b[1;32m 67\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshow_jupyter\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 68\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 69\u001b[0;31m \u001b[0manalyzer\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_jupyter\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 70\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mImportError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0merr\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 71\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlogger\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdebug\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0merr\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/cave/analyzer/base_analyzer.py\u001b[0m in \u001b[0;36mget_jupyter\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 96\u001b[0m \u001b[0moutput_notebook\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 97\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mbokeh_plot\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mbokeh_plots\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 98\u001b[0;31m \u001b[0mshow\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbokeh_plot\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 99\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 100\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mIPython\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcore\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdisplay\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mHTML\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdisplay\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/bokeh/io/showing.py\u001b[0m in \u001b[0;36mshow\u001b[0;34m(obj, browser, new, notebook_handle, notebook_url, **kw)\u001b[0m\n\u001b[1;32m 134\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 135\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mobj\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mLayoutDOM\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0mis_application\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0mcallable\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mobj\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 136\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0m_BAD_SHOW_MSG\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 137\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 138\u001b[0m \u001b[0;31m# TODO (bev) check callable signature more thoroughly\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mValueError\u001b[0m: \"Invalid object to show. The object to passed to show must be one of:\n\n* a LayoutDOM (e.g. a Plot or Widget or Layout)\n* a Bokeh Application\n* a callable suitable to an application FunctionHandler\n" + ] + } + ], + "source": [ + "cave.pimp_forward_selection()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "cave.cave_ablation()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "cave.cave_fanova()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "cave.local_parameter_importance()" + ] + }, { "cell_type": "code", "execution_count": null, @@ -316,6 +3878,13 @@ "print(eval_stats)\n" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, { "cell_type": "code", "execution_count": null, @@ -340,7 +3909,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.9" + "version": "3.6.12" } }, "nbformat": 4, diff --git a/run_experiments.py b/run_experiments.py index cfa9cd1..db51cfc 100644 --- a/run_experiments.py +++ b/run_experiments.py @@ -42,6 +42,10 @@ def main(): if(framework == "stable_baselines"): import run_experiments_baselines run_experiments_baselines.main(args) + elif( framework == "custom"): + import run_experiments_custom + run_experiments_custom.main(args) + return else: #ray import run_experiments_ray run_experiments_ray.main(args)#_ray.main(args) From f43d43052f64aa45f152b767644351bfa7ca25bb Mon Sep 17 00:00:00 2001 From: JessicaBorja Date: Thu, 18 Feb 2021 18:28:19 +0100 Subject: [PATCH 02/22] add multiple runs csv to analysis --- mdp_playground/analysis/mdpp_to_cave.py | 37 +- plot_experiments.ipynb | 3508 +---------------------- 2 files changed, 41 insertions(+), 3504 deletions(-) diff --git a/mdp_playground/analysis/mdpp_to_cave.py b/mdp_playground/analysis/mdpp_to_cave.py index 87703a1..180f468 100644 --- a/mdp_playground/analysis/mdpp_to_cave.py +++ b/mdp_playground/analysis/mdpp_to_cave.py @@ -59,6 +59,37 @@ def _create_run_history(self, stats_pd, seed_idx, col_names, output_folder, var_ runhistory_df[var] = stats_pd[var].iloc[final_rows_for_a_config] return runhistory_df + def join_files(self, file_prefix, file_suffix): + '''Utility to join files that were written with different experiment configs''' + with open(file_prefix + file_suffix, 'ab') as combined_file: + i = 0 + num_diff_lines = [] + while True: + if os.path.isfile(file_prefix + '_' + str(i) + file_suffix): + with open(file_prefix + '_' + str(i) + file_suffix, 'rb') as curr_file: + byte_string = curr_file.read() + newline_count = byte_string.count(10) + num_diff_lines.append(newline_count) + # if newline_count != 21 and file_suffix == '.csv': #hack to check only train files and not eval + # warnings.warn('Expected 21 \\n chars in each stats file because we usually write stats every 1k timesteps for 20k timesteps. However, this can easily differ, e.g., for TD3 and DDPG where learning starts at 2k timesteps and there is 1 less \\n. Got only: ' + str(newline_count) + ' in file: ' + str(i)) + combined_file.write(byte_string) + else: + break + i += 1 + print(str(i) + " files were combined into 1 for file:" + file_prefix + '_n' + file_suffix) + # print("Files missing for config_nums:", missing_configs, ". Did you pass the right value for max_total_configs as an argument?") + # print("Unique line count values:", np.unique(num_diff_lines)) + if i==0: + raise FileNotFoundError("No files to combine were present. Please check your location and/or filenames that they are correct.") + + def _read_stats(self, stats_file): + if os.path.isfile(stats_file + '.csv'): + print("\033[1;31mLoading data from a sequential run/already combined runs of experiment configurations.\033[0;0m") + else: + print("\033[1;31mLoading data from a distributed run of experiment configurations. Creating a combined CSV stats file.\033[0;0m") + self.join_files(stats_file, '.csv') + self.join_files(stats_file, '_eval.csv') + def to_cave_csv(self, args): #file_path = args.file_path input_folder = "../mdp_files/" @@ -117,6 +148,7 @@ def to_bohb_results(self, dir_name, exp_name): ## Read current csvs ## stats_file = os.path.join(dir_name, exp_name) + self._read_stats(stats_file) with open(stats_file + '.csv') as file_: col_names = file_.readline().strip().split(', ') col_names[0] = col_names[0][2:] # to remove '# ' that was written @@ -204,7 +236,8 @@ def to_bohb_results(self, dir_name, exp_name): if __name__ == "__main__": dir_name = '../../../mdp_files/' - exp_name = 'dqn_seq_del' + exp_name = 'rainbow_image_representations_tune_hps_cave_analysis' + dir_name += exp_name from cave.cavefacade import CAVE import os @@ -214,7 +247,7 @@ def to_bohb_results(self, dir_name, exp_name): mdpp_cave = MDPPToCave(output_dir) cave_input_file = mdpp_cave.to_bohb_results(dir_name, exp_name) - cave_input_file = "../../../mdpp_to_cave/dqn_seq_del" + #cave_input_file = "../../../mdpp_to_cave/dqn_seq_del" # Similarly, as an example, cave will ouput it's results # to the same directory as cave's input files diff --git a/plot_experiments.ipynb b/plot_experiments.ipynb index 8663fc3..980dc18 100644 --- a/plot_experiments.ipynb +++ b/plot_experiments.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -117,20 +117,9 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/sklearn/utils/deprecation.py:143: FutureWarning: The sklearn.metrics.regression module is deprecated in version 0.22 and will be removed in version 0.24. The corresponding classes / functions should instead be imported from sklearn.metrics. Anything that cannot be imported from sklearn.metrics is now part of the private API.\n", - " warnings.warn(message, FutureWarning)\n", - "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/sklearn/utils/deprecation.py:143: FutureWarning: The sklearn.manifold.mds module is deprecated in version 0.22 and will be removed in version 0.24. The corresponding classes / functions should instead be imported from sklearn.manifold. Anything that cannot be imported from sklearn.manifold is now part of the private API.\n", - " warnings.warn(message, FutureWarning)\n" - ] - } - ], + "outputs": [], "source": [ "from cave.cavefacade import CAVE\n", "from mdp_playground.analysis.mdpp_to_cave import MDPPToCave\n", @@ -138,7 +127,6 @@ "\n", "#The converted mdpp csvs will be stored in output_dir\n", "output_dir = \"../mdpp_to_cave\"\n", - "mdpp_file = os.path.join(dir_name, exp_name)\n", "mdpp_cave = MDPPToCave(output_dir)\n", "cave_input_file = mdpp_cave.to_bohb_results(dir_name, exp_name)\n", "\n", @@ -158,3495 +146,11 @@ }, { "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n", - "
\n", - "
\n", - "
General

General information about the optimization scenario.

\n", - "
\n", - "
\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
# parameters2
Deterministic target algorithmTrue
Optimized run objectivequality
--------------------
Total time spent evaluating configurations18.00 sec
Average time per configuration (mean / std)0.90 sec (± 0.00)
# evaluated configurations20
# changed parameters (default to incumbent)2
Configuration originsRandom : 20
\n", - "
\n", - "
Budgets

Statistics related to the budgets used in this optimization.

\n", - "
\n", - "
\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
20000
Total time spent evaluating configurations18.00 sec
Average time per configuration (mean / std)0.90 sec (± 0.00)
# evaluated configurations20
# changed parameters (default to incumbent)2
Configuration originsRandom : 20
\n", - "
\n", - "
Configuration Space

The parameter configuration space. (See github.com/automl/ConfigSpace)

\n", - "
\n", - "
\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
ParameterTypeRange/ChoicesDefault
delayUniformIntegerHyperparameter[0, 8]4
sequence_lengthUniformIntegerHyperparameter[1, 4]3
\n", - "
\n", - "
" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cave.overview_table()" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n", - "
\n", - "
\n", - "
\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
DefaultIncumbent
--------------- Changed parameters: -------------------------
delay40
sequence_length31
\n", - "
\n", - "
" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cave.compare_default_incumbent()" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "\n", - "
\n", - "
\n", - "
\n", - " \n", - "
\n", - "
\n", - "
\n", - "
\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
DefaultIncumbent
Quality-32.566-88.246
\n", - "
\n", - "
\n", - "
\n", - " \n", - "
" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cave.performance_table()" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "
\n", - " \n", - " Loading BokehJS ...\n", - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "\n", - "(function(root) {\n", - " function now() {\n", - " return new Date();\n", - " }\n", - "\n", - " var force = true;\n", - "\n", - " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", - " root._bokeh_onload_callbacks = [];\n", - " root._bokeh_is_loading = undefined;\n", - " }\n", - "\n", - " var JS_MIME_TYPE = 'application/javascript';\n", - " var HTML_MIME_TYPE = 'text/html';\n", - " var EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n", - " var CLASS_NAME = 'output_bokeh rendered_html';\n", - "\n", - " /**\n", - " * Render data to the DOM node\n", - " */\n", - " function render(props, node) {\n", - " var script = document.createElement(\"script\");\n", - " node.appendChild(script);\n", - " }\n", - "\n", - " /**\n", - " * Handle when an output is cleared or removed\n", - " */\n", - " function handleClearOutput(event, handle) {\n", - " var cell = handle.cell;\n", - "\n", - " var id = cell.output_area._bokeh_element_id;\n", - " var server_id = cell.output_area._bokeh_server_id;\n", - " // Clean up Bokeh references\n", - " if (id != null && id in Bokeh.index) {\n", - " Bokeh.index[id].model.document.clear();\n", - " delete Bokeh.index[id];\n", - " }\n", - "\n", - " if (server_id !== undefined) {\n", - " // Clean up Bokeh references\n", - " var cmd = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n", - " cell.notebook.kernel.execute(cmd, {\n", - " iopub: {\n", - " output: function(msg) {\n", - " var id = msg.content.text.trim();\n", - " if (id in Bokeh.index) {\n", - " Bokeh.index[id].model.document.clear();\n", - " delete Bokeh.index[id];\n", - " }\n", - " }\n", - " }\n", - " });\n", - " // Destroy server and session\n", - " var cmd = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n", - " cell.notebook.kernel.execute(cmd);\n", - " }\n", - " }\n", - "\n", - " /**\n", - " * Handle when a new output is added\n", - " */\n", - " function handleAddOutput(event, handle) {\n", - " var output_area = handle.output_area;\n", - " var output = handle.output;\n", - "\n", - " // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n", - " if ((output.output_type != \"display_data\") || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", - " return\n", - " }\n", - "\n", - " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", - "\n", - " if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n", - " toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n", - " // store reference to embed id on output_area\n", - " output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", - " }\n", - " if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", - " var bk_div = document.createElement(\"div\");\n", - " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", - " var script_attrs = bk_div.children[0].attributes;\n", - " for (var i = 0; i < script_attrs.length; i++) {\n", - " toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n", - " }\n", - " // store reference to server id on output_area\n", - " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", - " }\n", - " }\n", - "\n", - " function register_renderer(events, OutputArea) {\n", - "\n", - " function append_mime(data, metadata, element) {\n", - " // create a DOM node to render to\n", - " var toinsert = this.create_output_subarea(\n", - " metadata,\n", - " CLASS_NAME,\n", - " EXEC_MIME_TYPE\n", - " );\n", - " this.keyboard_manager.register_events(toinsert);\n", - " // Render to node\n", - " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", - " render(props, toinsert[toinsert.length - 1]);\n", - " element.append(toinsert);\n", - " return toinsert\n", - " }\n", - "\n", - " /* Handle when an output is cleared or removed */\n", - " events.on('clear_output.CodeCell', handleClearOutput);\n", - " events.on('delete.Cell', handleClearOutput);\n", - "\n", - " /* Handle when a new output is added */\n", - " events.on('output_added.OutputArea', handleAddOutput);\n", - "\n", - " /**\n", - " * Register the mime type and append_mime function with output_area\n", - " */\n", - " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", - " /* Is output safe? */\n", - " safe: true,\n", - " /* Index of renderer in `output_area.display_order` */\n", - " index: 0\n", - " });\n", - " }\n", - "\n", - " // register the mime type if in Jupyter Notebook environment and previously unregistered\n", - " if (root.Jupyter !== undefined) {\n", - " var events = require('base/js/events');\n", - " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", - "\n", - " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", - " register_renderer(events, OutputArea);\n", - " }\n", - " }\n", - "\n", - " \n", - " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", - " root._bokeh_timeout = Date.now() + 5000;\n", - " root._bokeh_failed_load = false;\n", - " }\n", - "\n", - " var NB_LOAD_WARNING = {'data': {'text/html':\n", - " \"
\\n\"+\n", - " \"

\\n\"+\n", - " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", - " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", - " \"

\\n\"+\n", - " \"
    \\n\"+\n", - " \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n", - " \"
  • use INLINE resources instead, as so:
  • \\n\"+\n", - " \"
\\n\"+\n", - " \"\\n\"+\n", - " \"from bokeh.resources import INLINE\\n\"+\n", - " \"output_notebook(resources=INLINE)\\n\"+\n", - " \"\\n\"+\n", - " \"
\"}};\n", - "\n", - " function display_loaded() {\n", - " var el = document.getElementById(\"1005\");\n", - " if (el != null) {\n", - " el.textContent = \"BokehJS is loading...\";\n", - " }\n", - " if (root.Bokeh !== undefined) {\n", - " if (el != null) {\n", - " el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n", - " }\n", - " } else if (Date.now() < root._bokeh_timeout) {\n", - " setTimeout(display_loaded, 100)\n", - " }\n", - " }\n", - "\n", - "\n", - " function run_callbacks() {\n", - " try {\n", - " root._bokeh_onload_callbacks.forEach(function(callback) {\n", - " if (callback != null)\n", - " callback();\n", - " });\n", - " } finally {\n", - " delete root._bokeh_onload_callbacks\n", - " }\n", - " console.debug(\"Bokeh: all callbacks have finished\");\n", - " }\n", - "\n", - " function load_libs(css_urls, js_urls, callback) {\n", - " if (css_urls == null) css_urls = [];\n", - " if (js_urls == null) js_urls = [];\n", - "\n", - " root._bokeh_onload_callbacks.push(callback);\n", - " if (root._bokeh_is_loading > 0) {\n", - " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", - " return null;\n", - " }\n", - " if (js_urls == null || js_urls.length === 0) {\n", - " run_callbacks();\n", - " return null;\n", - " }\n", - " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", - " root._bokeh_is_loading = css_urls.length + js_urls.length;\n", - "\n", - " function on_load() {\n", - " root._bokeh_is_loading--;\n", - " if (root._bokeh_is_loading === 0) {\n", - " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", - " run_callbacks()\n", - " }\n", - " }\n", - "\n", - " function on_error() {\n", - " console.error(\"failed to load \" + url);\n", - " }\n", - "\n", - " for (var i = 0; i < css_urls.length; i++) {\n", - " var url = css_urls[i];\n", - " const element = document.createElement(\"link\");\n", - " element.onload = on_load;\n", - " element.onerror = on_error;\n", - " element.rel = \"stylesheet\";\n", - " element.type = \"text/css\";\n", - " element.href = url;\n", - " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", - " document.body.appendChild(element);\n", - " }\n", - "\n", - " for (var i = 0; i < js_urls.length; i++) {\n", - " var url = js_urls[i];\n", - " var element = document.createElement('script');\n", - " element.onload = on_load;\n", - " element.onerror = on_error;\n", - " element.async = false;\n", - " element.src = url;\n", - " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", - " document.head.appendChild(element);\n", - " }\n", - " };var element = document.getElementById(\"1005\");\n", - " if (element == null) {\n", - " console.error(\"Bokeh: ERROR: autoload.js configured with elementid '1005' but no matching script tag was found. \")\n", - " return false;\n", - " }\n", - "\n", - " function inject_raw_css(css) {\n", - " const element = document.createElement(\"style\");\n", - " element.appendChild(document.createTextNode(css));\n", - " document.body.appendChild(element);\n", - " }\n", - "\n", - " var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.1.0.min.js\"];\n", - " var css_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.css\"];\n", - "\n", - " var inline_js = [\n", - " function(Bokeh) {\n", - " Bokeh.set_log_level(\"info\");\n", - " },\n", - " \n", - " function(Bokeh) {\n", - " (function(root, factory) {\n", - " // if(typeof exports === 'object' && typeof module === 'object')\n", - " // factory(require(\"Bokeh\"));\n", - " // else if(typeof define === 'function' && define.amd)\n", - " // define([\"Bokeh\"], factory);\n", - " // else if(typeof exports === 'object')\n", - " // factory(require(\"Bokeh\"));\n", - " // else\n", - " factory(root[\"Bokeh\"]);\n", - " })(this, function(Bokeh) {\n", - " var define;\n", - " return (function outer(modules, entry) {\n", - " if (Bokeh != null) {\n", - " return Bokeh.register_plugin(modules, {}, entry);\n", - " } else {\n", - " throw new Error(\"Cannot find Bokeh. You have to load it prior to loading plugins.\");\n", - " }\n", - " })\n", - " ({\n", - " \"custom/main\": function(require, module, exports) {\n", - " var models = {\n", - " \"ParallelResetTool\": require(\"custom/cave.plot.parallel_plot.parallel_reset.parallel_reset_tool\").ParallelResetTool,\n", - " \"ParallelSelectionTool\": require(\"custom/cave.plot.parallel_plot.parallel_selection_tool.parallel_selection_tool\").ParallelSelectionTool\n", - " };\n", - " require(\"base\").register_models(models);\n", - " module.exports = models;\n", - " },\n", - " \"custom/cave.plot.parallel_plot.parallel_reset.parallel_reset_tool\": function(require, module, exports) {\n", - " \"use strict\";\n", - " var __extends = (this && this.__extends) || (function () {\n", - " var extendStatics = function (d, b) {\n", - " extendStatics = Object.setPrototypeOf ||\n", - " ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n", - " function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n", - " return extendStatics(d, b);\n", - " };\n", - " return function (d, b) {\n", - " extendStatics(d, b);\n", - " function __() { this.constructor = d; }\n", - " d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n", - " };\n", - " })();\n", - " Object.defineProperty(exports, \"__esModule\", { value: true });\n", - " var action_tool_1 = require(\"models/tools/actions/action_tool\");\n", - " var ParallelResetToolView = /** @class */ (function (_super) {\n", - " __extends(ParallelResetToolView, _super);\n", - " function ParallelResetToolView() {\n", - " return _super !== null && _super.apply(this, arguments) || this;\n", - " }\n", - " ParallelResetToolView.prototype.doit = function () {\n", - " this.plot_view.reset_range();\n", - " };\n", - " return ParallelResetToolView;\n", - " }(action_tool_1.ActionToolView));\n", - " exports.ParallelResetToolView = ParallelResetToolView;\n", - " var ParallelResetTool = /** @class */ (function (_super) {\n", - " __extends(ParallelResetTool, _super);\n", - " function ParallelResetTool(attrs) {\n", - " var _this = _super.call(this, attrs) || this;\n", - " _this.tool_name = \"Reset Zoom\";\n", - " _this.icon = \"bk-tool-icon-reset\";\n", - " return _this;\n", - " }\n", - " ParallelResetTool.initClass = function () {\n", - " this.prototype.type = \"ParallelResetTool\";\n", - " this.prototype.default_view = ParallelResetToolView;\n", - " };\n", - " return ParallelResetTool;\n", - " }(action_tool_1.ActionTool));\n", - " exports.ParallelResetTool = ParallelResetTool;\n", - " ParallelResetTool.initClass();\n", - "\n", - " },\n", - " \"custom/cave.plot.parallel_plot.parallel_selection_tool.parallel_selection_tool\": function(require, module, exports) {\n", - " \"use strict\";\n", - " var __extends = (this && this.__extends) || (function () {\n", - " var extendStatics = function (d, b) {\n", - " extendStatics = Object.setPrototypeOf ||\n", - " ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n", - " function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n", - " return extendStatics(d, b);\n", - " };\n", - " return function (d, b) {\n", - " extendStatics(d, b);\n", - " function __() { this.constructor = d; }\n", - " d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n", - " };\n", - " })();\n", - " Object.defineProperty(exports, \"__esModule\", { value: true });\n", - " var p = require(\"core/properties\");\n", - " var box_select_tool_1 = require(\"models/tools/gestures/box_select_tool\");\n", - " var array_1 = require(\"core/util/array\");\n", - " var dom_1 = require(\"core/dom\");\n", - " function find_indices_in(array, _a) {\n", - " var inf = _a[0], sup = _a[1];\n", - " return array.reduce(function (prev, curr, index) {\n", - " return (inf <= curr && curr <= sup) ? prev.concat(index) : prev;\n", - " }, []);\n", - " }\n", - " function index_array(array, indices) {\n", - " return indices.reduce(function (a, i) { return a.concat(array[i]); }, []);\n", - " }\n", - " function combineByKey(key, array) {\n", - " var keys = Object.keys(array[0]);\n", - " var combined = [];\n", - " array.forEach(function (itm) {\n", - " var idx = combined.map(function (item) { return item[key]; }).indexOf(itm[key]);\n", - " if (idx >= 0) {\n", - " keys.forEach(function (element) {\n", - " if (element != key)\n", - " combined[idx][element].push(itm[element]);\n", - " });\n", - " }\n", - " else {\n", - " var new_object_1 = {};\n", - " keys.forEach(function (element) {\n", - " if (element == key) {\n", - " new_object_1[element] = itm[element];\n", - " }\n", - " else {\n", - " new_object_1[element] = [itm[element]];\n", - " }\n", - " });\n", - " combined.push(new_object_1);\n", - " }\n", - " });\n", - " return combined;\n", - " }\n", - " var ParallelSelectionView = /** @class */ (function (_super) {\n", - " __extends(ParallelSelectionView, _super);\n", - " function ParallelSelectionView() {\n", - " var _this = _super !== null && _super.apply(this, arguments) || this;\n", - " _this.selection_mode = \"add\";\n", - " _this.panning = false;\n", - " return _this;\n", - " }\n", - " ParallelSelectionView.prototype.initialize = function () {\n", - " var _this = this;\n", - " _super.prototype.initialize.call(this);\n", - " var frame = this.plot_view.frame;\n", - " var _a = this.model.renderer_select, x_range_name_select = _a.x_range_name, y_range_name_select = _a.y_range_name;\n", - " var _b = this.model.renderer_data, x_range_name_data = _b.x_range_name, y_range_name_data = _b.y_range_name;\n", - " if (x_range_name_select == x_range_name_data && y_range_name_select == y_range_name_data) {\n", - " this.xscale = frame.xscales[x_range_name_select];\n", - " this.yscale = frame.yscales[y_range_name_select];\n", - " }\n", - " else\n", - " throw new Error(\"selection and data does not share the same ranges\");\n", - " //TODO test if parallel CDS is valid (xs for each line should be identical)\n", - " this.glyph_select = this.model.renderer_select.glyph;\n", - " this.glyph_data = this.model.renderer_data.glyph;\n", - " this.cds_select = this.model.renderer_select.data_source;\n", - " this.cds_data = this.model.renderer_data.data_source;\n", - " var _c = [this.glyph_data.xs.field, this.glyph_data.ys.field], xskey = _c[0], yskey = _c[1];\n", - " this.xdata = this.cds_data.get_array(xskey)[0];\n", - " this.ydataT = array_1.transpose(this.cds_data.get_array(yskey));\n", - " this.selection_indices = [];\n", - " this.connect(this.plot_view.frame.x_ranges[this.model.renderer_select.x_range_name].change, function () { return _this._resize_boxes_on_zoom(); });\n", - " this.connect(this.cds_select.change, function () { return _this._update_data_selection(); });\n", - " };\n", - " Object.defineProperty(ParallelSelectionView.prototype, \"_box_width\", {\n", - " get: function () {\n", - " return this.xscale.invert(this.model.box_width) - this.xscale.invert(0);\n", - " },\n", - " enumerable: true,\n", - " configurable: true\n", - " });\n", - " Object.defineProperty(ParallelSelectionView.prototype, \"_cds_select_keys\", {\n", - " get: function () {\n", - " var glyph_select = this.glyph_select;\n", - " var _a = [glyph_select.x.field, glyph_select.y.field], xkey = _a[0], ykey = _a[1];\n", - " var _b = [glyph_select.width.field, glyph_select.height.field], wkey = _b[0], hkey = _b[1];\n", - " return { xkey: xkey, ykey: ykey, wkey: wkey, hkey: hkey };\n", - " },\n", - " enumerable: true,\n", - " configurable: true\n", - " });\n", - " ParallelSelectionView.prototype._emit_cds_changes = function (cds, redraw, clear, emit) {\n", - " if (redraw === void 0) { redraw = true; }\n", - " if (clear === void 0) { clear = true; }\n", - " if (emit === void 0) { emit = true; }\n", - " if (clear)\n", - " cds.selection_manager.clear();\n", - " if (redraw)\n", - " cds.change.emit();\n", - " if (emit) {\n", - " cds.data = cds.data;\n", - " cds.properties.data.change.emit();\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._box_paramaters = function (index) {\n", - " var _a = this._cds_select_keys, xkey = _a.xkey, ykey = _a.ykey, wkey = _a.wkey, hkey = _a.hkey;\n", - " var x = this.cds_select.get_array(xkey)[index];\n", - " var y = this.cds_select.get_array(ykey)[index];\n", - " var w = this.cds_select.get_array(wkey)[index];\n", - " var h = this.cds_select.get_array(hkey)[index];\n", - " return { x: x, y: y, w: w, h: h };\n", - " };\n", - " ParallelSelectionView.prototype._hit_test_boxes = function (sx, sy) {\n", - " var nboxes = this.cds_select.get_length();\n", - " if (nboxes != 0 && nboxes != null) {\n", - " var _a = [this.xscale.invert(sx), this.yscale.invert(sy)], xtest = _a[0], ytest = _a[1];\n", - " for (var i = 0; i < nboxes; i++) {\n", - " var _b = this._box_paramaters(i), x = _b.x, y = _b.y, w = _b.w, h = _b.h;\n", - " if (xtest >= (x - w / 2) && xtest <= x + w / 2 &&\n", - " ytest >= (y - h / 2) && ytest <= y + h / 2) {\n", - " return i;\n", - " }\n", - " }\n", - " }\n", - " return null;\n", - " };\n", - " ParallelSelectionView.prototype._resize_boxes_on_zoom = function () {\n", - " //resize selection boxes when zooming to keep a constant (pixel) size\n", - " var cds = this.cds_select;\n", - " var array_width = cds.get_array(this.glyph_select.width.field);\n", - " var new_width = this._box_width;\n", - " array_width.forEach(function (_, i) { return array_width[i] = new_width; });\n", - " this._emit_cds_changes(cds, true, false, false);\n", - " };\n", - " ParallelSelectionView.prototype._drag_start = function (ev) {\n", - " //Save y position of the drag start\n", - " if (this.ind_active_box != null) {\n", - " this._base_point = [this.xscale.invert(ev.sx), this.yscale.invert(ev.sy)];\n", - " this._base_box_parameters = this._box_paramaters(this.ind_active_box);\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._update_box_ypos = function (index_box, delta_y) {\n", - " if (this._base_box_parameters != null) {\n", - " var cds = this.cds_select;\n", - " var ykey = this._cds_select_keys.ykey;\n", - " var _a = this._base_box_parameters, current_y = _a.y, h = _a.h;\n", - " var new_y = current_y + delta_y;\n", - " new_y = new_y - Math.max(0, (new_y + h / 2) - 1) - Math.min(0, (new_y - h / 2));\n", - " cds.get_array(ykey)[index_box] = new_y;\n", - " this._emit_cds_changes(cds, true, false, false);\n", - " this._update_selection_indices(index_box, [new_y - h / 2, new_y + h / 2]);\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._drag = function (ev) {\n", - " if (this.ind_active_box != null && this._base_point != null) {\n", - " var delta_y = this.yscale.invert(ev.sy) - this._base_point[1];\n", - " this._update_box_ypos(this.ind_active_box, delta_y);\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._drag_stop = function (_ev) {\n", - " this._base_point = null;\n", - " this._base_box_parameters = null;\n", - " };\n", - " ParallelSelectionView.prototype._pan_start = function (ev) {\n", - " this.panning = true;\n", - " switch (this.selection_mode) {\n", - " case \"add\": {\n", - " _super.prototype._pan_start.call(this, ev);\n", - " break;\n", - " }\n", - " case \"drag\": {\n", - " this._drag_start(ev);\n", - " break;\n", - " }\n", - " case \"resize\": {\n", - " break;\n", - " }\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._pan = function (ev) {\n", - " switch (this.selection_mode) {\n", - " case \"add\": {\n", - " _super.prototype._pan.call(this, ev);\n", - " break;\n", - " }\n", - " case \"drag\": {\n", - " this._drag(ev);\n", - " break;\n", - " }\n", - " case \"resize\": {\n", - " break;\n", - " }\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._pan_end = function (ev) {\n", - " switch (this.selection_mode) {\n", - " case \"add\": {\n", - " _super.prototype._pan_end.call(this, ev);\n", - " break;\n", - " }\n", - " case \"drag\": {\n", - " this._drag_stop(ev);\n", - " break;\n", - " }\n", - " case \"resize\": {\n", - " break;\n", - " }\n", - " }\n", - " this.panning = false;\n", - " };\n", - " ParallelSelectionView.prototype._move = function (ev) {\n", - " //Switch mode\n", - " if (this.panning) {\n", - " return;\n", - " }\n", - " this.ind_active_box = this._hit_test_boxes(ev.sx, ev.sy);\n", - " if (this.ind_active_box != null) {\n", - " this.selection_mode = \"drag\";\n", - " }\n", - " else {\n", - " this.selection_mode = \"add\";\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._doubletap = function (_ev) {\n", - " var _this = this;\n", - " //delete box on double tap\n", - " if (this.ind_active_box != null) {\n", - " this.cds_select.columns().forEach(function (key) {\n", - " _this.cds_select.get_array(key).splice(_this.ind_active_box, 1);\n", - " });\n", - " this._delete_selection_indices(this.ind_active_box);\n", - " this._emit_cds_changes(this.cds_select);\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._keyup = function (ev) {\n", - " var _this = this;\n", - " if (ev.keyCode == dom_1.Keys.Esc) {\n", - " var nelems_1 = this.cds_select.get_length();\n", - " if (nelems_1 != null) {\n", - " this.cds_select.columns().forEach(function (key) {\n", - " _this.cds_select.get_array(key).splice(0, nelems_1);\n", - " });\n", - " this.selection_indices.splice(0, nelems_1);\n", - " this._emit_cds_changes(this.cds_select);\n", - " }\n", - " this.plot_view.request_render();\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._update_data_selection = function () {\n", - " var selection_indices = [];\n", - " if (this.selection_indices.length > 0) {\n", - " var combined_selections = combineByKey('data_idx', this.selection_indices);\n", - " selection_indices = array_1.intersection.apply(void 0, [array_1.union.apply(void 0, combined_selections[0].indices)].concat(combined_selections.slice(1).map(function (elem) { return array_1.union.apply(void 0, elem.indices); })));\n", - " }\n", - " this.cds_data.selected.indices = selection_indices;\n", - " this.cds_data.change.emit();\n", - " };\n", - " ParallelSelectionView.prototype._make_selection_indices = function (indices, _a) {\n", - " var _this = this;\n", - " var _b;\n", - " var y0 = _a[0], y1 = _a[1];\n", - " (_b = this.selection_indices).push.apply(_b, indices.map(function (index) {\n", - " return {\n", - " data_idx: index,\n", - " indices: find_indices_in(_this.ydataT[index], [y0, y1]),\n", - " };\n", - " }));\n", - " };\n", - " ParallelSelectionView.prototype._update_selection_indices = function (index, _a) {\n", - " var y0 = _a[0], y1 = _a[1];\n", - " this.selection_indices[index].indices = find_indices_in(this.ydataT[this.selection_indices[index].data_idx], [y0, y1]);\n", - " };\n", - " ParallelSelectionView.prototype._delete_selection_indices = function (index) {\n", - " this.selection_indices.splice(index, 1);\n", - " };\n", - " ParallelSelectionView.prototype._make_box_select = function (xs, _a) {\n", - " var _this = this;\n", - " var y0 = _a[0], y1 = _a[1];\n", - " y0 = Math.max(0, y0);\n", - " y1 = Math.min(1, y1);\n", - " var y = (y0 + y1) / 2.;\n", - " var w = this._box_width;\n", - " var h = y1 - y0;\n", - " var _b = this._cds_select_keys, xkey = _b.xkey, ykey = _b.ykey, wkey = _b.wkey, hkey = _b.hkey;\n", - " xs.forEach(function (x) {\n", - " if (xkey)\n", - " _this.cds_select.get_array(xkey).push(x);\n", - " if (ykey)\n", - " _this.cds_select.get_array(ykey).push(y);\n", - " if (wkey)\n", - " _this.cds_select.get_array(wkey).push(w);\n", - " if (hkey)\n", - " _this.cds_select.get_array(hkey).push(h);\n", - " });\n", - " this._emit_cds_changes(this.cds_select);\n", - " };\n", - " ParallelSelectionView.prototype._do_select = function (_a, _b, _final, _append) {\n", - " var sx0 = _a[0], sx1 = _a[1];\n", - " var sy0 = _b[0], sy1 = _b[1];\n", - " if (_final === void 0) { _final = true; }\n", - " if (_append === void 0) { _append = true; }\n", - " // Get selection bbox in the data space\n", - " var _c = this.xscale.r_invert(sx0, sx1), x0 = _c[0], x1 = _c[1];\n", - " var _d = this.yscale.r_invert(sy0, sy1), y0 = _d[0], y1 = _d[1];\n", - " var x_indices = find_indices_in(this.xdata, [x0, x1]);\n", - " var xs = index_array(this.xdata, x_indices);\n", - " this._make_selection_indices(x_indices, [y0, y1]);\n", - " this._make_box_select(xs, [y0, y1]);\n", - " };\n", - " return ParallelSelectionView;\n", - " }(box_select_tool_1.BoxSelectToolView));\n", - " exports.ParallelSelectionView = ParallelSelectionView;\n", - " var ParallelSelectionTool = /** @class */ (function (_super) {\n", - " __extends(ParallelSelectionTool, _super);\n", - " function ParallelSelectionTool() {\n", - " var _this = _super !== null && _super.apply(this, arguments) || this;\n", - " _this.tool_name = \"Parallel Selection\";\n", - " //override event_type property define in BoxSelectTool\n", - " _this.event_type = [\"tap\", \"pan\", \"move\"];\n", - " return _this;\n", - " }\n", - " ParallelSelectionTool.initClass = function () {\n", - " this.prototype.type = \"ParallelSelectionTool\";\n", - " this.prototype.default_view = ParallelSelectionView;\n", - " this.define({\n", - " renderer_select: [p.Any],\n", - " renderer_data: [p.Any],\n", - " box_width: [p.Number, 30],\n", - " });\n", - " };\n", - " return ParallelSelectionTool;\n", - " }(box_select_tool_1.BoxSelectTool));\n", - " exports.ParallelSelectionTool = ParallelSelectionTool;\n", - " ParallelSelectionTool.initClass();\n", - "\n", - " }\n", - " }, \"custom/main\");\n", - " ;\n", - " });\n", - "\n", - " },\n", - " function(Bokeh) {} // ensure no trailing comma for IE\n", - " ];\n", - "\n", - " function run_inline_js() {\n", - " \n", - " if ((root.Bokeh !== undefined) || (force === true)) {\n", - " for (var i = 0; i < inline_js.length; i++) {\n", - " inline_js[i].call(root, root.Bokeh);\n", - " }if (force === true) {\n", - " display_loaded();\n", - " }} else if (Date.now() < root._bokeh_timeout) {\n", - " setTimeout(run_inline_js, 100);\n", - " } else if (!root._bokeh_failed_load) {\n", - " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", - " root._bokeh_failed_load = true;\n", - " } else if (force !== true) {\n", - " var cell = $(document.getElementById(\"1005\")).parents('.cell').data().cell;\n", - " cell.output_area.append_execute_result(NB_LOAD_WARNING)\n", - " }\n", - "\n", - " }\n", - "\n", - " if (root._bokeh_is_loading === 0) {\n", - " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", - " run_inline_js();\n", - " } else {\n", - " load_libs(css_urls, js_urls, function() {\n", - " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", - " run_inline_js();\n", - " });\n", - " }\n", - "}(window));" - ], - "application/vnd.bokehjs_load.v0+json": "\n(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n \n\n \n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n var NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n var el = document.getElementById(\"1005\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };var element = document.getElementById(\"1005\");\n if (element == null) {\n console.error(\"Bokeh: ERROR: autoload.js configured with elementid '1005' but no matching script tag was found. \")\n return false;\n }\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.1.0.min.js\"];\n var css_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.css\"];\n\n var inline_js = [\n function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n \n function(Bokeh) {\n (function(root, factory) {\n // if(typeof exports === 'object' && typeof module === 'object')\n // factory(require(\"Bokeh\"));\n // else if(typeof define === 'function' && define.amd)\n // define([\"Bokeh\"], factory);\n // else if(typeof exports === 'object')\n // factory(require(\"Bokeh\"));\n // else\n factory(root[\"Bokeh\"]);\n })(this, function(Bokeh) {\n var define;\n return (function outer(modules, entry) {\n if (Bokeh != null) {\n return Bokeh.register_plugin(modules, {}, entry);\n } else {\n throw new Error(\"Cannot find Bokeh. You have to load it prior to loading plugins.\");\n }\n })\n ({\n \"custom/main\": function(require, module, exports) {\n var models = {\n \"ParallelResetTool\": require(\"custom/cave.plot.parallel_plot.parallel_reset.parallel_reset_tool\").ParallelResetTool,\n \"ParallelSelectionTool\": require(\"custom/cave.plot.parallel_plot.parallel_selection_tool.parallel_selection_tool\").ParallelSelectionTool\n };\n require(\"base\").register_models(models);\n module.exports = models;\n },\n \"custom/cave.plot.parallel_plot.parallel_reset.parallel_reset_tool\": function(require, module, exports) {\n \"use strict\";\n var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n })();\n Object.defineProperty(exports, \"__esModule\", { value: true });\n var action_tool_1 = require(\"models/tools/actions/action_tool\");\n var ParallelResetToolView = /** @class */ (function (_super) {\n __extends(ParallelResetToolView, _super);\n function ParallelResetToolView() {\n return _super !== null && _super.apply(this, arguments) || this;\n }\n ParallelResetToolView.prototype.doit = function () {\n this.plot_view.reset_range();\n };\n return ParallelResetToolView;\n }(action_tool_1.ActionToolView));\n exports.ParallelResetToolView = ParallelResetToolView;\n var ParallelResetTool = /** @class */ (function (_super) {\n __extends(ParallelResetTool, _super);\n function ParallelResetTool(attrs) {\n var _this = _super.call(this, attrs) || this;\n _this.tool_name = \"Reset Zoom\";\n _this.icon = \"bk-tool-icon-reset\";\n return _this;\n }\n ParallelResetTool.initClass = function () {\n this.prototype.type = \"ParallelResetTool\";\n this.prototype.default_view = ParallelResetToolView;\n };\n return ParallelResetTool;\n }(action_tool_1.ActionTool));\n exports.ParallelResetTool = ParallelResetTool;\n ParallelResetTool.initClass();\n\n },\n \"custom/cave.plot.parallel_plot.parallel_selection_tool.parallel_selection_tool\": function(require, module, exports) {\n \"use strict\";\n var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n })();\n Object.defineProperty(exports, \"__esModule\", { value: true });\n var p = require(\"core/properties\");\n var box_select_tool_1 = require(\"models/tools/gestures/box_select_tool\");\n var array_1 = require(\"core/util/array\");\n var dom_1 = require(\"core/dom\");\n function find_indices_in(array, _a) {\n var inf = _a[0], sup = _a[1];\n return array.reduce(function (prev, curr, index) {\n return (inf <= curr && curr <= sup) ? prev.concat(index) : prev;\n }, []);\n }\n function index_array(array, indices) {\n return indices.reduce(function (a, i) { return a.concat(array[i]); }, []);\n }\n function combineByKey(key, array) {\n var keys = Object.keys(array[0]);\n var combined = [];\n array.forEach(function (itm) {\n var idx = combined.map(function (item) { return item[key]; }).indexOf(itm[key]);\n if (idx >= 0) {\n keys.forEach(function (element) {\n if (element != key)\n combined[idx][element].push(itm[element]);\n });\n }\n else {\n var new_object_1 = {};\n keys.forEach(function (element) {\n if (element == key) {\n new_object_1[element] = itm[element];\n }\n else {\n new_object_1[element] = [itm[element]];\n }\n });\n combined.push(new_object_1);\n }\n });\n return combined;\n }\n var ParallelSelectionView = /** @class */ (function (_super) {\n __extends(ParallelSelectionView, _super);\n function ParallelSelectionView() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n _this.selection_mode = \"add\";\n _this.panning = false;\n return _this;\n }\n ParallelSelectionView.prototype.initialize = function () {\n var _this = this;\n _super.prototype.initialize.call(this);\n var frame = this.plot_view.frame;\n var _a = this.model.renderer_select, x_range_name_select = _a.x_range_name, y_range_name_select = _a.y_range_name;\n var _b = this.model.renderer_data, x_range_name_data = _b.x_range_name, y_range_name_data = _b.y_range_name;\n if (x_range_name_select == x_range_name_data && y_range_name_select == y_range_name_data) {\n this.xscale = frame.xscales[x_range_name_select];\n this.yscale = frame.yscales[y_range_name_select];\n }\n else\n throw new Error(\"selection and data does not share the same ranges\");\n //TODO test if parallel CDS is valid (xs for each line should be identical)\n this.glyph_select = this.model.renderer_select.glyph;\n this.glyph_data = this.model.renderer_data.glyph;\n this.cds_select = this.model.renderer_select.data_source;\n this.cds_data = this.model.renderer_data.data_source;\n var _c = [this.glyph_data.xs.field, this.glyph_data.ys.field], xskey = _c[0], yskey = _c[1];\n this.xdata = this.cds_data.get_array(xskey)[0];\n this.ydataT = array_1.transpose(this.cds_data.get_array(yskey));\n this.selection_indices = [];\n this.connect(this.plot_view.frame.x_ranges[this.model.renderer_select.x_range_name].change, function () { return _this._resize_boxes_on_zoom(); });\n this.connect(this.cds_select.change, function () { return _this._update_data_selection(); });\n };\n Object.defineProperty(ParallelSelectionView.prototype, \"_box_width\", {\n get: function () {\n return this.xscale.invert(this.model.box_width) - this.xscale.invert(0);\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(ParallelSelectionView.prototype, \"_cds_select_keys\", {\n get: function () {\n var glyph_select = this.glyph_select;\n var _a = [glyph_select.x.field, glyph_select.y.field], xkey = _a[0], ykey = _a[1];\n var _b = [glyph_select.width.field, glyph_select.height.field], wkey = _b[0], hkey = _b[1];\n return { xkey: xkey, ykey: ykey, wkey: wkey, hkey: hkey };\n },\n enumerable: true,\n configurable: true\n });\n ParallelSelectionView.prototype._emit_cds_changes = function (cds, redraw, clear, emit) {\n if (redraw === void 0) { redraw = true; }\n if (clear === void 0) { clear = true; }\n if (emit === void 0) { emit = true; }\n if (clear)\n cds.selection_manager.clear();\n if (redraw)\n cds.change.emit();\n if (emit) {\n cds.data = cds.data;\n cds.properties.data.change.emit();\n }\n };\n ParallelSelectionView.prototype._box_paramaters = function (index) {\n var _a = this._cds_select_keys, xkey = _a.xkey, ykey = _a.ykey, wkey = _a.wkey, hkey = _a.hkey;\n var x = this.cds_select.get_array(xkey)[index];\n var y = this.cds_select.get_array(ykey)[index];\n var w = this.cds_select.get_array(wkey)[index];\n var h = this.cds_select.get_array(hkey)[index];\n return { x: x, y: y, w: w, h: h };\n };\n ParallelSelectionView.prototype._hit_test_boxes = function (sx, sy) {\n var nboxes = this.cds_select.get_length();\n if (nboxes != 0 && nboxes != null) {\n var _a = [this.xscale.invert(sx), this.yscale.invert(sy)], xtest = _a[0], ytest = _a[1];\n for (var i = 0; i < nboxes; i++) {\n var _b = this._box_paramaters(i), x = _b.x, y = _b.y, w = _b.w, h = _b.h;\n if (xtest >= (x - w / 2) && xtest <= x + w / 2 &&\n ytest >= (y - h / 2) && ytest <= y + h / 2) {\n return i;\n }\n }\n }\n return null;\n };\n ParallelSelectionView.prototype._resize_boxes_on_zoom = function () {\n //resize selection boxes when zooming to keep a constant (pixel) size\n var cds = this.cds_select;\n var array_width = cds.get_array(this.glyph_select.width.field);\n var new_width = this._box_width;\n array_width.forEach(function (_, i) { return array_width[i] = new_width; });\n this._emit_cds_changes(cds, true, false, false);\n };\n ParallelSelectionView.prototype._drag_start = function (ev) {\n //Save y position of the drag start\n if (this.ind_active_box != null) {\n this._base_point = [this.xscale.invert(ev.sx), this.yscale.invert(ev.sy)];\n this._base_box_parameters = this._box_paramaters(this.ind_active_box);\n }\n };\n ParallelSelectionView.prototype._update_box_ypos = function (index_box, delta_y) {\n if (this._base_box_parameters != null) {\n var cds = this.cds_select;\n var ykey = this._cds_select_keys.ykey;\n var _a = this._base_box_parameters, current_y = _a.y, h = _a.h;\n var new_y = current_y + delta_y;\n new_y = new_y - Math.max(0, (new_y + h / 2) - 1) - Math.min(0, (new_y - h / 2));\n cds.get_array(ykey)[index_box] = new_y;\n this._emit_cds_changes(cds, true, false, false);\n this._update_selection_indices(index_box, [new_y - h / 2, new_y + h / 2]);\n }\n };\n ParallelSelectionView.prototype._drag = function (ev) {\n if (this.ind_active_box != null && this._base_point != null) {\n var delta_y = this.yscale.invert(ev.sy) - this._base_point[1];\n this._update_box_ypos(this.ind_active_box, delta_y);\n }\n };\n ParallelSelectionView.prototype._drag_stop = function (_ev) {\n this._base_point = null;\n this._base_box_parameters = null;\n };\n ParallelSelectionView.prototype._pan_start = function (ev) {\n this.panning = true;\n switch (this.selection_mode) {\n case \"add\": {\n _super.prototype._pan_start.call(this, ev);\n break;\n }\n case \"drag\": {\n this._drag_start(ev);\n break;\n }\n case \"resize\": {\n break;\n }\n }\n };\n ParallelSelectionView.prototype._pan = function (ev) {\n switch (this.selection_mode) {\n case \"add\": {\n _super.prototype._pan.call(this, ev);\n break;\n }\n case \"drag\": {\n this._drag(ev);\n break;\n }\n case \"resize\": {\n break;\n }\n }\n };\n ParallelSelectionView.prototype._pan_end = function (ev) {\n switch (this.selection_mode) {\n case \"add\": {\n _super.prototype._pan_end.call(this, ev);\n break;\n }\n case \"drag\": {\n this._drag_stop(ev);\n break;\n }\n case \"resize\": {\n break;\n }\n }\n this.panning = false;\n };\n ParallelSelectionView.prototype._move = function (ev) {\n //Switch mode\n if (this.panning) {\n return;\n }\n this.ind_active_box = this._hit_test_boxes(ev.sx, ev.sy);\n if (this.ind_active_box != null) {\n this.selection_mode = \"drag\";\n }\n else {\n this.selection_mode = \"add\";\n }\n };\n ParallelSelectionView.prototype._doubletap = function (_ev) {\n var _this = this;\n //delete box on double tap\n if (this.ind_active_box != null) {\n this.cds_select.columns().forEach(function (key) {\n _this.cds_select.get_array(key).splice(_this.ind_active_box, 1);\n });\n this._delete_selection_indices(this.ind_active_box);\n this._emit_cds_changes(this.cds_select);\n }\n };\n ParallelSelectionView.prototype._keyup = function (ev) {\n var _this = this;\n if (ev.keyCode == dom_1.Keys.Esc) {\n var nelems_1 = this.cds_select.get_length();\n if (nelems_1 != null) {\n this.cds_select.columns().forEach(function (key) {\n _this.cds_select.get_array(key).splice(0, nelems_1);\n });\n this.selection_indices.splice(0, nelems_1);\n this._emit_cds_changes(this.cds_select);\n }\n this.plot_view.request_render();\n }\n };\n ParallelSelectionView.prototype._update_data_selection = function () {\n var selection_indices = [];\n if (this.selection_indices.length > 0) {\n var combined_selections = combineByKey('data_idx', this.selection_indices);\n selection_indices = array_1.intersection.apply(void 0, [array_1.union.apply(void 0, combined_selections[0].indices)].concat(combined_selections.slice(1).map(function (elem) { return array_1.union.apply(void 0, elem.indices); })));\n }\n this.cds_data.selected.indices = selection_indices;\n this.cds_data.change.emit();\n };\n ParallelSelectionView.prototype._make_selection_indices = function (indices, _a) {\n var _this = this;\n var _b;\n var y0 = _a[0], y1 = _a[1];\n (_b = this.selection_indices).push.apply(_b, indices.map(function (index) {\n return {\n data_idx: index,\n indices: find_indices_in(_this.ydataT[index], [y0, y1]),\n };\n }));\n };\n ParallelSelectionView.prototype._update_selection_indices = function (index, _a) {\n var y0 = _a[0], y1 = _a[1];\n this.selection_indices[index].indices = find_indices_in(this.ydataT[this.selection_indices[index].data_idx], [y0, y1]);\n };\n ParallelSelectionView.prototype._delete_selection_indices = function (index) {\n this.selection_indices.splice(index, 1);\n };\n ParallelSelectionView.prototype._make_box_select = function (xs, _a) {\n var _this = this;\n var y0 = _a[0], y1 = _a[1];\n y0 = Math.max(0, y0);\n y1 = Math.min(1, y1);\n var y = (y0 + y1) / 2.;\n var w = this._box_width;\n var h = y1 - y0;\n var _b = this._cds_select_keys, xkey = _b.xkey, ykey = _b.ykey, wkey = _b.wkey, hkey = _b.hkey;\n xs.forEach(function (x) {\n if (xkey)\n _this.cds_select.get_array(xkey).push(x);\n if (ykey)\n _this.cds_select.get_array(ykey).push(y);\n if (wkey)\n _this.cds_select.get_array(wkey).push(w);\n if (hkey)\n _this.cds_select.get_array(hkey).push(h);\n });\n this._emit_cds_changes(this.cds_select);\n };\n ParallelSelectionView.prototype._do_select = function (_a, _b, _final, _append) {\n var sx0 = _a[0], sx1 = _a[1];\n var sy0 = _b[0], sy1 = _b[1];\n if (_final === void 0) { _final = true; }\n if (_append === void 0) { _append = true; }\n // Get selection bbox in the data space\n var _c = this.xscale.r_invert(sx0, sx1), x0 = _c[0], x1 = _c[1];\n var _d = this.yscale.r_invert(sy0, sy1), y0 = _d[0], y1 = _d[1];\n var x_indices = find_indices_in(this.xdata, [x0, x1]);\n var xs = index_array(this.xdata, x_indices);\n this._make_selection_indices(x_indices, [y0, y1]);\n this._make_box_select(xs, [y0, y1]);\n };\n return ParallelSelectionView;\n }(box_select_tool_1.BoxSelectToolView));\n exports.ParallelSelectionView = ParallelSelectionView;\n var ParallelSelectionTool = /** @class */ (function (_super) {\n __extends(ParallelSelectionTool, _super);\n function ParallelSelectionTool() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n _this.tool_name = \"Parallel Selection\";\n //override event_type property define in BoxSelectTool\n _this.event_type = [\"tap\", \"pan\", \"move\"];\n return _this;\n }\n ParallelSelectionTool.initClass = function () {\n this.prototype.type = \"ParallelSelectionTool\";\n this.prototype.default_view = ParallelSelectionView;\n this.define({\n renderer_select: [p.Any],\n renderer_data: [p.Any],\n box_width: [p.Number, 30],\n });\n };\n return ParallelSelectionTool;\n }(box_select_tool_1.BoxSelectTool));\n exports.ParallelSelectionTool = ParallelSelectionTool;\n ParallelSelectionTool.initClass();\n\n }\n }, \"custom/main\");\n ;\n });\n\n },\n function(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n \n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }if (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n var cell = $(document.getElementById(\"1005\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "(function(root) {\n", - " function embed_document(root) {\n", - " \n", - " var docs_json = {\"a844f449-2791-4215-a47f-20ccd4d4db43\":{\"roots\":{\"references\":[{\"attributes\":{\"columns\":[{\"id\":\"1002\",\"type\":\"TableColumn\"}],\"height\":20,\"index_position\":null,\"source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"},\"view\":{\"id\":\"1004\",\"type\":\"CDSView\"}},\"id\":\"1003\",\"type\":\"DataTable\"},{\"attributes\":{},\"id\":\"1007\",\"type\":\"StringEditor\"},{\"attributes\":{\"callback\":null,\"data\":{\"Parameters\":[]},\"selected\":{\"id\":\"1008\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1009\",\"type\":\"UnionRenderers\"}},\"id\":\"1001\",\"type\":\"ColumnDataSource\"},{\"attributes\":{},\"id\":\"1006\",\"type\":\"StringFormatter\"},{\"attributes\":{\"source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"}},\"id\":\"1004\",\"type\":\"CDSView\"},{\"attributes\":{\"default_sort\":\"descending\",\"editor\":{\"id\":\"1007\",\"type\":\"StringEditor\"},\"field\":\"Parameters\",\"formatter\":{\"id\":\"1006\",\"type\":\"StringFormatter\"},\"sortable\":false,\"title\":\"Parameters\",\"width\":150},\"id\":\"1002\",\"type\":\"TableColumn\"},{\"attributes\":{},\"id\":\"1008\",\"type\":\"Selection\"},{\"attributes\":{},\"id\":\"1009\",\"type\":\"UnionRenderers\"}],\"root_ids\":[\"1003\"]},\"title\":\"Bokeh Application\",\"version\":\"1.1.0\"}};\n", - " var render_items = [{\"docid\":\"a844f449-2791-4215-a47f-20ccd4d4db43\",\"roots\":{\"1003\":\"3710ea7b-cdcc-4825-840d-92930f9ced97\"}}];\n", - " root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", - "\n", - " }\n", - " if (root.Bokeh !== undefined) {\n", - " embed_document(root);\n", - " } else {\n", - " var attempts = 0;\n", - " var timer = setInterval(function(root) {\n", - " if (root.Bokeh !== undefined) {\n", - " embed_document(root);\n", - " clearInterval(timer);\n", - " }\n", - " attempts++;\n", - " if (attempts > 100) {\n", - " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n", - " clearInterval(timer);\n", - " }\n", - " }, 10, root)\n", - " }\n", - "})(window);" - ], - "application/vnd.bokehjs_exec.v0+json": "" - }, - "metadata": { - "application/vnd.bokehjs_exec.v0+json": { - "id": "1003" - } - }, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cave.pimp_comparison_table()" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "#As there are no instances, this will not show\n", - "cave.plot_scatter()\n", - "cave.plot_ecdf()\n", - "cave.algorithm_footprints()" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "
\n", - " \n", - " Loading BokehJS ...\n", - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "\n", - "(function(root) {\n", - " function now() {\n", - " return new Date();\n", - " }\n", - "\n", - " var force = true;\n", - "\n", - " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", - " root._bokeh_onload_callbacks = [];\n", - " root._bokeh_is_loading = undefined;\n", - " }\n", - "\n", - " var JS_MIME_TYPE = 'application/javascript';\n", - " var HTML_MIME_TYPE = 'text/html';\n", - " var EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n", - " var CLASS_NAME = 'output_bokeh rendered_html';\n", - "\n", - " /**\n", - " * Render data to the DOM node\n", - " */\n", - " function render(props, node) {\n", - " var script = document.createElement(\"script\");\n", - " node.appendChild(script);\n", - " }\n", - "\n", - " /**\n", - " * Handle when an output is cleared or removed\n", - " */\n", - " function handleClearOutput(event, handle) {\n", - " var cell = handle.cell;\n", - "\n", - " var id = cell.output_area._bokeh_element_id;\n", - " var server_id = cell.output_area._bokeh_server_id;\n", - " // Clean up Bokeh references\n", - " if (id != null && id in Bokeh.index) {\n", - " Bokeh.index[id].model.document.clear();\n", - " delete Bokeh.index[id];\n", - " }\n", - "\n", - " if (server_id !== undefined) {\n", - " // Clean up Bokeh references\n", - " var cmd = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n", - " cell.notebook.kernel.execute(cmd, {\n", - " iopub: {\n", - " output: function(msg) {\n", - " var id = msg.content.text.trim();\n", - " if (id in Bokeh.index) {\n", - " Bokeh.index[id].model.document.clear();\n", - " delete Bokeh.index[id];\n", - " }\n", - " }\n", - " }\n", - " });\n", - " // Destroy server and session\n", - " var cmd = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n", - " cell.notebook.kernel.execute(cmd);\n", - " }\n", - " }\n", - "\n", - " /**\n", - " * Handle when a new output is added\n", - " */\n", - " function handleAddOutput(event, handle) {\n", - " var output_area = handle.output_area;\n", - " var output = handle.output;\n", - "\n", - " // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n", - " if ((output.output_type != \"display_data\") || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", - " return\n", - " }\n", - "\n", - " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", - "\n", - " if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n", - " toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n", - " // store reference to embed id on output_area\n", - " output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", - " }\n", - " if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", - " var bk_div = document.createElement(\"div\");\n", - " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", - " var script_attrs = bk_div.children[0].attributes;\n", - " for (var i = 0; i < script_attrs.length; i++) {\n", - " toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n", - " }\n", - " // store reference to server id on output_area\n", - " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", - " }\n", - " }\n", - "\n", - " function register_renderer(events, OutputArea) {\n", - "\n", - " function append_mime(data, metadata, element) {\n", - " // create a DOM node to render to\n", - " var toinsert = this.create_output_subarea(\n", - " metadata,\n", - " CLASS_NAME,\n", - " EXEC_MIME_TYPE\n", - " );\n", - " this.keyboard_manager.register_events(toinsert);\n", - " // Render to node\n", - " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", - " render(props, toinsert[toinsert.length - 1]);\n", - " element.append(toinsert);\n", - " return toinsert\n", - " }\n", - "\n", - " /* Handle when an output is cleared or removed */\n", - " events.on('clear_output.CodeCell', handleClearOutput);\n", - " events.on('delete.Cell', handleClearOutput);\n", - "\n", - " /* Handle when a new output is added */\n", - " events.on('output_added.OutputArea', handleAddOutput);\n", - "\n", - " /**\n", - " * Register the mime type and append_mime function with output_area\n", - " */\n", - " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", - " /* Is output safe? */\n", - " safe: true,\n", - " /* Index of renderer in `output_area.display_order` */\n", - " index: 0\n", - " });\n", - " }\n", - "\n", - " // register the mime type if in Jupyter Notebook environment and previously unregistered\n", - " if (root.Jupyter !== undefined) {\n", - " var events = require('base/js/events');\n", - " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", - "\n", - " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", - " register_renderer(events, OutputArea);\n", - " }\n", - " }\n", - "\n", - " \n", - " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", - " root._bokeh_timeout = Date.now() + 5000;\n", - " root._bokeh_failed_load = false;\n", - " }\n", - "\n", - " var NB_LOAD_WARNING = {'data': {'text/html':\n", - " \"
\\n\"+\n", - " \"

\\n\"+\n", - " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", - " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", - " \"

\\n\"+\n", - " \"
    \\n\"+\n", - " \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n", - " \"
  • use INLINE resources instead, as so:
  • \\n\"+\n", - " \"
\\n\"+\n", - " \"\\n\"+\n", - " \"from bokeh.resources import INLINE\\n\"+\n", - " \"output_notebook(resources=INLINE)\\n\"+\n", - " \"\\n\"+\n", - " \"
\"}};\n", - "\n", - " function display_loaded() {\n", - " var el = document.getElementById(\"4897\");\n", - " if (el != null) {\n", - " el.textContent = \"BokehJS is loading...\";\n", - " }\n", - " if (root.Bokeh !== undefined) {\n", - " if (el != null) {\n", - " el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n", - " }\n", - " } else if (Date.now() < root._bokeh_timeout) {\n", - " setTimeout(display_loaded, 100)\n", - " }\n", - " }\n", - "\n", - "\n", - " function run_callbacks() {\n", - " try {\n", - " root._bokeh_onload_callbacks.forEach(function(callback) {\n", - " if (callback != null)\n", - " callback();\n", - " });\n", - " } finally {\n", - " delete root._bokeh_onload_callbacks\n", - " }\n", - " console.debug(\"Bokeh: all callbacks have finished\");\n", - " }\n", - "\n", - " function load_libs(css_urls, js_urls, callback) {\n", - " if (css_urls == null) css_urls = [];\n", - " if (js_urls == null) js_urls = [];\n", - "\n", - " root._bokeh_onload_callbacks.push(callback);\n", - " if (root._bokeh_is_loading > 0) {\n", - " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", - " return null;\n", - " }\n", - " if (js_urls == null || js_urls.length === 0) {\n", - " run_callbacks();\n", - " return null;\n", - " }\n", - " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", - " root._bokeh_is_loading = css_urls.length + js_urls.length;\n", - "\n", - " function on_load() {\n", - " root._bokeh_is_loading--;\n", - " if (root._bokeh_is_loading === 0) {\n", - " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", - " run_callbacks()\n", - " }\n", - " }\n", - "\n", - " function on_error() {\n", - " console.error(\"failed to load \" + url);\n", - " }\n", - "\n", - " for (var i = 0; i < css_urls.length; i++) {\n", - " var url = css_urls[i];\n", - " const element = document.createElement(\"link\");\n", - " element.onload = on_load;\n", - " element.onerror = on_error;\n", - " element.rel = \"stylesheet\";\n", - " element.type = \"text/css\";\n", - " element.href = url;\n", - " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", - " document.body.appendChild(element);\n", - " }\n", - "\n", - " for (var i = 0; i < js_urls.length; i++) {\n", - " var url = js_urls[i];\n", - " var element = document.createElement('script');\n", - " element.onload = on_load;\n", - " element.onerror = on_error;\n", - " element.async = false;\n", - " element.src = url;\n", - " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", - " document.head.appendChild(element);\n", - " }\n", - " };var element = document.getElementById(\"4897\");\n", - " if (element == null) {\n", - " console.error(\"Bokeh: ERROR: autoload.js configured with elementid '4897' but no matching script tag was found. \")\n", - " return false;\n", - " }\n", - "\n", - " function inject_raw_css(css) {\n", - " const element = document.createElement(\"style\");\n", - " element.appendChild(document.createTextNode(css));\n", - " document.body.appendChild(element);\n", - " }\n", - "\n", - " var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.1.0.min.js\"];\n", - " var css_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.css\"];\n", - "\n", - " var inline_js = [\n", - " function(Bokeh) {\n", - " Bokeh.set_log_level(\"info\");\n", - " },\n", - " \n", - " function(Bokeh) {\n", - " (function(root, factory) {\n", - " // if(typeof exports === 'object' && typeof module === 'object')\n", - " // factory(require(\"Bokeh\"));\n", - " // else if(typeof define === 'function' && define.amd)\n", - " // define([\"Bokeh\"], factory);\n", - " // else if(typeof exports === 'object')\n", - " // factory(require(\"Bokeh\"));\n", - " // else\n", - " factory(root[\"Bokeh\"]);\n", - " })(this, function(Bokeh) {\n", - " var define;\n", - " return (function outer(modules, entry) {\n", - " if (Bokeh != null) {\n", - " return Bokeh.register_plugin(modules, {}, entry);\n", - " } else {\n", - " throw new Error(\"Cannot find Bokeh. You have to load it prior to loading plugins.\");\n", - " }\n", - " })\n", - " ({\n", - " \"custom/main\": function(require, module, exports) {\n", - " var models = {\n", - " \"ParallelResetTool\": require(\"custom/cave.plot.parallel_plot.parallel_reset.parallel_reset_tool\").ParallelResetTool,\n", - " \"ParallelSelectionTool\": require(\"custom/cave.plot.parallel_plot.parallel_selection_tool.parallel_selection_tool\").ParallelSelectionTool\n", - " };\n", - " require(\"base\").register_models(models);\n", - " module.exports = models;\n", - " },\n", - " \"custom/cave.plot.parallel_plot.parallel_reset.parallel_reset_tool\": function(require, module, exports) {\n", - " \"use strict\";\n", - " var __extends = (this && this.__extends) || (function () {\n", - " var extendStatics = function (d, b) {\n", - " extendStatics = Object.setPrototypeOf ||\n", - " ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n", - " function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n", - " return extendStatics(d, b);\n", - " };\n", - " return function (d, b) {\n", - " extendStatics(d, b);\n", - " function __() { this.constructor = d; }\n", - " d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n", - " };\n", - " })();\n", - " Object.defineProperty(exports, \"__esModule\", { value: true });\n", - " var action_tool_1 = require(\"models/tools/actions/action_tool\");\n", - " var ParallelResetToolView = /** @class */ (function (_super) {\n", - " __extends(ParallelResetToolView, _super);\n", - " function ParallelResetToolView() {\n", - " return _super !== null && _super.apply(this, arguments) || this;\n", - " }\n", - " ParallelResetToolView.prototype.doit = function () {\n", - " this.plot_view.reset_range();\n", - " };\n", - " return ParallelResetToolView;\n", - " }(action_tool_1.ActionToolView));\n", - " exports.ParallelResetToolView = ParallelResetToolView;\n", - " var ParallelResetTool = /** @class */ (function (_super) {\n", - " __extends(ParallelResetTool, _super);\n", - " function ParallelResetTool(attrs) {\n", - " var _this = _super.call(this, attrs) || this;\n", - " _this.tool_name = \"Reset Zoom\";\n", - " _this.icon = \"bk-tool-icon-reset\";\n", - " return _this;\n", - " }\n", - " ParallelResetTool.initClass = function () {\n", - " this.prototype.type = \"ParallelResetTool\";\n", - " this.prototype.default_view = ParallelResetToolView;\n", - " };\n", - " return ParallelResetTool;\n", - " }(action_tool_1.ActionTool));\n", - " exports.ParallelResetTool = ParallelResetTool;\n", - " ParallelResetTool.initClass();\n", - "\n", - " },\n", - " \"custom/cave.plot.parallel_plot.parallel_selection_tool.parallel_selection_tool\": function(require, module, exports) {\n", - " \"use strict\";\n", - " var __extends = (this && this.__extends) || (function () {\n", - " var extendStatics = function (d, b) {\n", - " extendStatics = Object.setPrototypeOf ||\n", - " ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n", - " function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n", - " return extendStatics(d, b);\n", - " };\n", - " return function (d, b) {\n", - " extendStatics(d, b);\n", - " function __() { this.constructor = d; }\n", - " d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n", - " };\n", - " })();\n", - " Object.defineProperty(exports, \"__esModule\", { value: true });\n", - " var p = require(\"core/properties\");\n", - " var box_select_tool_1 = require(\"models/tools/gestures/box_select_tool\");\n", - " var array_1 = require(\"core/util/array\");\n", - " var dom_1 = require(\"core/dom\");\n", - " function find_indices_in(array, _a) {\n", - " var inf = _a[0], sup = _a[1];\n", - " return array.reduce(function (prev, curr, index) {\n", - " return (inf <= curr && curr <= sup) ? prev.concat(index) : prev;\n", - " }, []);\n", - " }\n", - " function index_array(array, indices) {\n", - " return indices.reduce(function (a, i) { return a.concat(array[i]); }, []);\n", - " }\n", - " function combineByKey(key, array) {\n", - " var keys = Object.keys(array[0]);\n", - " var combined = [];\n", - " array.forEach(function (itm) {\n", - " var idx = combined.map(function (item) { return item[key]; }).indexOf(itm[key]);\n", - " if (idx >= 0) {\n", - " keys.forEach(function (element) {\n", - " if (element != key)\n", - " combined[idx][element].push(itm[element]);\n", - " });\n", - " }\n", - " else {\n", - " var new_object_1 = {};\n", - " keys.forEach(function (element) {\n", - " if (element == key) {\n", - " new_object_1[element] = itm[element];\n", - " }\n", - " else {\n", - " new_object_1[element] = [itm[element]];\n", - " }\n", - " });\n", - " combined.push(new_object_1);\n", - " }\n", - " });\n", - " return combined;\n", - " }\n", - " var ParallelSelectionView = /** @class */ (function (_super) {\n", - " __extends(ParallelSelectionView, _super);\n", - " function ParallelSelectionView() {\n", - " var _this = _super !== null && _super.apply(this, arguments) || this;\n", - " _this.selection_mode = \"add\";\n", - " _this.panning = false;\n", - " return _this;\n", - " }\n", - " ParallelSelectionView.prototype.initialize = function () {\n", - " var _this = this;\n", - " _super.prototype.initialize.call(this);\n", - " var frame = this.plot_view.frame;\n", - " var _a = this.model.renderer_select, x_range_name_select = _a.x_range_name, y_range_name_select = _a.y_range_name;\n", - " var _b = this.model.renderer_data, x_range_name_data = _b.x_range_name, y_range_name_data = _b.y_range_name;\n", - " if (x_range_name_select == x_range_name_data && y_range_name_select == y_range_name_data) {\n", - " this.xscale = frame.xscales[x_range_name_select];\n", - " this.yscale = frame.yscales[y_range_name_select];\n", - " }\n", - " else\n", - " throw new Error(\"selection and data does not share the same ranges\");\n", - " //TODO test if parallel CDS is valid (xs for each line should be identical)\n", - " this.glyph_select = this.model.renderer_select.glyph;\n", - " this.glyph_data = this.model.renderer_data.glyph;\n", - " this.cds_select = this.model.renderer_select.data_source;\n", - " this.cds_data = this.model.renderer_data.data_source;\n", - " var _c = [this.glyph_data.xs.field, this.glyph_data.ys.field], xskey = _c[0], yskey = _c[1];\n", - " this.xdata = this.cds_data.get_array(xskey)[0];\n", - " this.ydataT = array_1.transpose(this.cds_data.get_array(yskey));\n", - " this.selection_indices = [];\n", - " this.connect(this.plot_view.frame.x_ranges[this.model.renderer_select.x_range_name].change, function () { return _this._resize_boxes_on_zoom(); });\n", - " this.connect(this.cds_select.change, function () { return _this._update_data_selection(); });\n", - " };\n", - " Object.defineProperty(ParallelSelectionView.prototype, \"_box_width\", {\n", - " get: function () {\n", - " return this.xscale.invert(this.model.box_width) - this.xscale.invert(0);\n", - " },\n", - " enumerable: true,\n", - " configurable: true\n", - " });\n", - " Object.defineProperty(ParallelSelectionView.prototype, \"_cds_select_keys\", {\n", - " get: function () {\n", - " var glyph_select = this.glyph_select;\n", - " var _a = [glyph_select.x.field, glyph_select.y.field], xkey = _a[0], ykey = _a[1];\n", - " var _b = [glyph_select.width.field, glyph_select.height.field], wkey = _b[0], hkey = _b[1];\n", - " return { xkey: xkey, ykey: ykey, wkey: wkey, hkey: hkey };\n", - " },\n", - " enumerable: true,\n", - " configurable: true\n", - " });\n", - " ParallelSelectionView.prototype._emit_cds_changes = function (cds, redraw, clear, emit) {\n", - " if (redraw === void 0) { redraw = true; }\n", - " if (clear === void 0) { clear = true; }\n", - " if (emit === void 0) { emit = true; }\n", - " if (clear)\n", - " cds.selection_manager.clear();\n", - " if (redraw)\n", - " cds.change.emit();\n", - " if (emit) {\n", - " cds.data = cds.data;\n", - " cds.properties.data.change.emit();\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._box_paramaters = function (index) {\n", - " var _a = this._cds_select_keys, xkey = _a.xkey, ykey = _a.ykey, wkey = _a.wkey, hkey = _a.hkey;\n", - " var x = this.cds_select.get_array(xkey)[index];\n", - " var y = this.cds_select.get_array(ykey)[index];\n", - " var w = this.cds_select.get_array(wkey)[index];\n", - " var h = this.cds_select.get_array(hkey)[index];\n", - " return { x: x, y: y, w: w, h: h };\n", - " };\n", - " ParallelSelectionView.prototype._hit_test_boxes = function (sx, sy) {\n", - " var nboxes = this.cds_select.get_length();\n", - " if (nboxes != 0 && nboxes != null) {\n", - " var _a = [this.xscale.invert(sx), this.yscale.invert(sy)], xtest = _a[0], ytest = _a[1];\n", - " for (var i = 0; i < nboxes; i++) {\n", - " var _b = this._box_paramaters(i), x = _b.x, y = _b.y, w = _b.w, h = _b.h;\n", - " if (xtest >= (x - w / 2) && xtest <= x + w / 2 &&\n", - " ytest >= (y - h / 2) && ytest <= y + h / 2) {\n", - " return i;\n", - " }\n", - " }\n", - " }\n", - " return null;\n", - " };\n", - " ParallelSelectionView.prototype._resize_boxes_on_zoom = function () {\n", - " //resize selection boxes when zooming to keep a constant (pixel) size\n", - " var cds = this.cds_select;\n", - " var array_width = cds.get_array(this.glyph_select.width.field);\n", - " var new_width = this._box_width;\n", - " array_width.forEach(function (_, i) { return array_width[i] = new_width; });\n", - " this._emit_cds_changes(cds, true, false, false);\n", - " };\n", - " ParallelSelectionView.prototype._drag_start = function (ev) {\n", - " //Save y position of the drag start\n", - " if (this.ind_active_box != null) {\n", - " this._base_point = [this.xscale.invert(ev.sx), this.yscale.invert(ev.sy)];\n", - " this._base_box_parameters = this._box_paramaters(this.ind_active_box);\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._update_box_ypos = function (index_box, delta_y) {\n", - " if (this._base_box_parameters != null) {\n", - " var cds = this.cds_select;\n", - " var ykey = this._cds_select_keys.ykey;\n", - " var _a = this._base_box_parameters, current_y = _a.y, h = _a.h;\n", - " var new_y = current_y + delta_y;\n", - " new_y = new_y - Math.max(0, (new_y + h / 2) - 1) - Math.min(0, (new_y - h / 2));\n", - " cds.get_array(ykey)[index_box] = new_y;\n", - " this._emit_cds_changes(cds, true, false, false);\n", - " this._update_selection_indices(index_box, [new_y - h / 2, new_y + h / 2]);\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._drag = function (ev) {\n", - " if (this.ind_active_box != null && this._base_point != null) {\n", - " var delta_y = this.yscale.invert(ev.sy) - this._base_point[1];\n", - " this._update_box_ypos(this.ind_active_box, delta_y);\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._drag_stop = function (_ev) {\n", - " this._base_point = null;\n", - " this._base_box_parameters = null;\n", - " };\n", - " ParallelSelectionView.prototype._pan_start = function (ev) {\n", - " this.panning = true;\n", - " switch (this.selection_mode) {\n", - " case \"add\": {\n", - " _super.prototype._pan_start.call(this, ev);\n", - " break;\n", - " }\n", - " case \"drag\": {\n", - " this._drag_start(ev);\n", - " break;\n", - " }\n", - " case \"resize\": {\n", - " break;\n", - " }\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._pan = function (ev) {\n", - " switch (this.selection_mode) {\n", - " case \"add\": {\n", - " _super.prototype._pan.call(this, ev);\n", - " break;\n", - " }\n", - " case \"drag\": {\n", - " this._drag(ev);\n", - " break;\n", - " }\n", - " case \"resize\": {\n", - " break;\n", - " }\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._pan_end = function (ev) {\n", - " switch (this.selection_mode) {\n", - " case \"add\": {\n", - " _super.prototype._pan_end.call(this, ev);\n", - " break;\n", - " }\n", - " case \"drag\": {\n", - " this._drag_stop(ev);\n", - " break;\n", - " }\n", - " case \"resize\": {\n", - " break;\n", - " }\n", - " }\n", - " this.panning = false;\n", - " };\n", - " ParallelSelectionView.prototype._move = function (ev) {\n", - " //Switch mode\n", - " if (this.panning) {\n", - " return;\n", - " }\n", - " this.ind_active_box = this._hit_test_boxes(ev.sx, ev.sy);\n", - " if (this.ind_active_box != null) {\n", - " this.selection_mode = \"drag\";\n", - " }\n", - " else {\n", - " this.selection_mode = \"add\";\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._doubletap = function (_ev) {\n", - " var _this = this;\n", - " //delete box on double tap\n", - " if (this.ind_active_box != null) {\n", - " this.cds_select.columns().forEach(function (key) {\n", - " _this.cds_select.get_array(key).splice(_this.ind_active_box, 1);\n", - " });\n", - " this._delete_selection_indices(this.ind_active_box);\n", - " this._emit_cds_changes(this.cds_select);\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._keyup = function (ev) {\n", - " var _this = this;\n", - " if (ev.keyCode == dom_1.Keys.Esc) {\n", - " var nelems_1 = this.cds_select.get_length();\n", - " if (nelems_1 != null) {\n", - " this.cds_select.columns().forEach(function (key) {\n", - " _this.cds_select.get_array(key).splice(0, nelems_1);\n", - " });\n", - " this.selection_indices.splice(0, nelems_1);\n", - " this._emit_cds_changes(this.cds_select);\n", - " }\n", - " this.plot_view.request_render();\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._update_data_selection = function () {\n", - " var selection_indices = [];\n", - " if (this.selection_indices.length > 0) {\n", - " var combined_selections = combineByKey('data_idx', this.selection_indices);\n", - " selection_indices = array_1.intersection.apply(void 0, [array_1.union.apply(void 0, combined_selections[0].indices)].concat(combined_selections.slice(1).map(function (elem) { return array_1.union.apply(void 0, elem.indices); })));\n", - " }\n", - " this.cds_data.selected.indices = selection_indices;\n", - " this.cds_data.change.emit();\n", - " };\n", - " ParallelSelectionView.prototype._make_selection_indices = function (indices, _a) {\n", - " var _this = this;\n", - " var _b;\n", - " var y0 = _a[0], y1 = _a[1];\n", - " (_b = this.selection_indices).push.apply(_b, indices.map(function (index) {\n", - " return {\n", - " data_idx: index,\n", - " indices: find_indices_in(_this.ydataT[index], [y0, y1]),\n", - " };\n", - " }));\n", - " };\n", - " ParallelSelectionView.prototype._update_selection_indices = function (index, _a) {\n", - " var y0 = _a[0], y1 = _a[1];\n", - " this.selection_indices[index].indices = find_indices_in(this.ydataT[this.selection_indices[index].data_idx], [y0, y1]);\n", - " };\n", - " ParallelSelectionView.prototype._delete_selection_indices = function (index) {\n", - " this.selection_indices.splice(index, 1);\n", - " };\n", - " ParallelSelectionView.prototype._make_box_select = function (xs, _a) {\n", - " var _this = this;\n", - " var y0 = _a[0], y1 = _a[1];\n", - " y0 = Math.max(0, y0);\n", - " y1 = Math.min(1, y1);\n", - " var y = (y0 + y1) / 2.;\n", - " var w = this._box_width;\n", - " var h = y1 - y0;\n", - " var _b = this._cds_select_keys, xkey = _b.xkey, ykey = _b.ykey, wkey = _b.wkey, hkey = _b.hkey;\n", - " xs.forEach(function (x) {\n", - " if (xkey)\n", - " _this.cds_select.get_array(xkey).push(x);\n", - " if (ykey)\n", - " _this.cds_select.get_array(ykey).push(y);\n", - " if (wkey)\n", - " _this.cds_select.get_array(wkey).push(w);\n", - " if (hkey)\n", - " _this.cds_select.get_array(hkey).push(h);\n", - " });\n", - " this._emit_cds_changes(this.cds_select);\n", - " };\n", - " ParallelSelectionView.prototype._do_select = function (_a, _b, _final, _append) {\n", - " var sx0 = _a[0], sx1 = _a[1];\n", - " var sy0 = _b[0], sy1 = _b[1];\n", - " if (_final === void 0) { _final = true; }\n", - " if (_append === void 0) { _append = true; }\n", - " // Get selection bbox in the data space\n", - " var _c = this.xscale.r_invert(sx0, sx1), x0 = _c[0], x1 = _c[1];\n", - " var _d = this.yscale.r_invert(sy0, sy1), y0 = _d[0], y1 = _d[1];\n", - " var x_indices = find_indices_in(this.xdata, [x0, x1]);\n", - " var xs = index_array(this.xdata, x_indices);\n", - " this._make_selection_indices(x_indices, [y0, y1]);\n", - " this._make_box_select(xs, [y0, y1]);\n", - " };\n", - " return ParallelSelectionView;\n", - " }(box_select_tool_1.BoxSelectToolView));\n", - " exports.ParallelSelectionView = ParallelSelectionView;\n", - " var ParallelSelectionTool = /** @class */ (function (_super) {\n", - " __extends(ParallelSelectionTool, _super);\n", - " function ParallelSelectionTool() {\n", - " var _this = _super !== null && _super.apply(this, arguments) || this;\n", - " _this.tool_name = \"Parallel Selection\";\n", - " //override event_type property define in BoxSelectTool\n", - " _this.event_type = [\"tap\", \"pan\", \"move\"];\n", - " return _this;\n", - " }\n", - " ParallelSelectionTool.initClass = function () {\n", - " this.prototype.type = \"ParallelSelectionTool\";\n", - " this.prototype.default_view = ParallelSelectionView;\n", - " this.define({\n", - " renderer_select: [p.Any],\n", - " renderer_data: [p.Any],\n", - " box_width: [p.Number, 30],\n", - " });\n", - " };\n", - " return ParallelSelectionTool;\n", - " }(box_select_tool_1.BoxSelectTool));\n", - " exports.ParallelSelectionTool = ParallelSelectionTool;\n", - " ParallelSelectionTool.initClass();\n", - "\n", - " }\n", - " }, \"custom/main\");\n", - " ;\n", - " });\n", - "\n", - " },\n", - " function(Bokeh) {} // ensure no trailing comma for IE\n", - " ];\n", - "\n", - " function run_inline_js() {\n", - " \n", - " if ((root.Bokeh !== undefined) || (force === true)) {\n", - " for (var i = 0; i < inline_js.length; i++) {\n", - " inline_js[i].call(root, root.Bokeh);\n", - " }if (force === true) {\n", - " display_loaded();\n", - " }} else if (Date.now() < root._bokeh_timeout) {\n", - " setTimeout(run_inline_js, 100);\n", - " } else if (!root._bokeh_failed_load) {\n", - " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", - " root._bokeh_failed_load = true;\n", - " } else if (force !== true) {\n", - " var cell = $(document.getElementById(\"4897\")).parents('.cell').data().cell;\n", - " cell.output_area.append_execute_result(NB_LOAD_WARNING)\n", - " }\n", - "\n", - " }\n", - "\n", - " if (root._bokeh_is_loading === 0) {\n", - " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", - " run_inline_js();\n", - " } else {\n", - " load_libs(css_urls, js_urls, function() {\n", - " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", - " run_inline_js();\n", - " });\n", - " }\n", - "}(window));" - ], - "application/vnd.bokehjs_load.v0+json": "\n(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n \n\n \n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n var NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n var el = document.getElementById(\"4897\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };var element = document.getElementById(\"4897\");\n if (element == null) {\n console.error(\"Bokeh: ERROR: autoload.js configured with elementid '4897' but no matching script tag was found. \")\n return false;\n }\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.1.0.min.js\"];\n var css_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.css\"];\n\n var inline_js = [\n function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n \n function(Bokeh) {\n (function(root, factory) {\n // if(typeof exports === 'object' && typeof module === 'object')\n // factory(require(\"Bokeh\"));\n // else if(typeof define === 'function' && define.amd)\n // define([\"Bokeh\"], factory);\n // else if(typeof exports === 'object')\n // factory(require(\"Bokeh\"));\n // else\n factory(root[\"Bokeh\"]);\n })(this, function(Bokeh) {\n var define;\n return (function outer(modules, entry) {\n if (Bokeh != null) {\n return Bokeh.register_plugin(modules, {}, entry);\n } else {\n throw new Error(\"Cannot find Bokeh. You have to load it prior to loading plugins.\");\n }\n })\n ({\n \"custom/main\": function(require, module, exports) {\n var models = {\n \"ParallelResetTool\": require(\"custom/cave.plot.parallel_plot.parallel_reset.parallel_reset_tool\").ParallelResetTool,\n \"ParallelSelectionTool\": require(\"custom/cave.plot.parallel_plot.parallel_selection_tool.parallel_selection_tool\").ParallelSelectionTool\n };\n require(\"base\").register_models(models);\n module.exports = models;\n },\n \"custom/cave.plot.parallel_plot.parallel_reset.parallel_reset_tool\": function(require, module, exports) {\n \"use strict\";\n var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n })();\n Object.defineProperty(exports, \"__esModule\", { value: true });\n var action_tool_1 = require(\"models/tools/actions/action_tool\");\n var ParallelResetToolView = /** @class */ (function (_super) {\n __extends(ParallelResetToolView, _super);\n function ParallelResetToolView() {\n return _super !== null && _super.apply(this, arguments) || this;\n }\n ParallelResetToolView.prototype.doit = function () {\n this.plot_view.reset_range();\n };\n return ParallelResetToolView;\n }(action_tool_1.ActionToolView));\n exports.ParallelResetToolView = ParallelResetToolView;\n var ParallelResetTool = /** @class */ (function (_super) {\n __extends(ParallelResetTool, _super);\n function ParallelResetTool(attrs) {\n var _this = _super.call(this, attrs) || this;\n _this.tool_name = \"Reset Zoom\";\n _this.icon = \"bk-tool-icon-reset\";\n return _this;\n }\n ParallelResetTool.initClass = function () {\n this.prototype.type = \"ParallelResetTool\";\n this.prototype.default_view = ParallelResetToolView;\n };\n return ParallelResetTool;\n }(action_tool_1.ActionTool));\n exports.ParallelResetTool = ParallelResetTool;\n ParallelResetTool.initClass();\n\n },\n \"custom/cave.plot.parallel_plot.parallel_selection_tool.parallel_selection_tool\": function(require, module, exports) {\n \"use strict\";\n var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n })();\n Object.defineProperty(exports, \"__esModule\", { value: true });\n var p = require(\"core/properties\");\n var box_select_tool_1 = require(\"models/tools/gestures/box_select_tool\");\n var array_1 = require(\"core/util/array\");\n var dom_1 = require(\"core/dom\");\n function find_indices_in(array, _a) {\n var inf = _a[0], sup = _a[1];\n return array.reduce(function (prev, curr, index) {\n return (inf <= curr && curr <= sup) ? prev.concat(index) : prev;\n }, []);\n }\n function index_array(array, indices) {\n return indices.reduce(function (a, i) { return a.concat(array[i]); }, []);\n }\n function combineByKey(key, array) {\n var keys = Object.keys(array[0]);\n var combined = [];\n array.forEach(function (itm) {\n var idx = combined.map(function (item) { return item[key]; }).indexOf(itm[key]);\n if (idx >= 0) {\n keys.forEach(function (element) {\n if (element != key)\n combined[idx][element].push(itm[element]);\n });\n }\n else {\n var new_object_1 = {};\n keys.forEach(function (element) {\n if (element == key) {\n new_object_1[element] = itm[element];\n }\n else {\n new_object_1[element] = [itm[element]];\n }\n });\n combined.push(new_object_1);\n }\n });\n return combined;\n }\n var ParallelSelectionView = /** @class */ (function (_super) {\n __extends(ParallelSelectionView, _super);\n function ParallelSelectionView() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n _this.selection_mode = \"add\";\n _this.panning = false;\n return _this;\n }\n ParallelSelectionView.prototype.initialize = function () {\n var _this = this;\n _super.prototype.initialize.call(this);\n var frame = this.plot_view.frame;\n var _a = this.model.renderer_select, x_range_name_select = _a.x_range_name, y_range_name_select = _a.y_range_name;\n var _b = this.model.renderer_data, x_range_name_data = _b.x_range_name, y_range_name_data = _b.y_range_name;\n if (x_range_name_select == x_range_name_data && y_range_name_select == y_range_name_data) {\n this.xscale = frame.xscales[x_range_name_select];\n this.yscale = frame.yscales[y_range_name_select];\n }\n else\n throw new Error(\"selection and data does not share the same ranges\");\n //TODO test if parallel CDS is valid (xs for each line should be identical)\n this.glyph_select = this.model.renderer_select.glyph;\n this.glyph_data = this.model.renderer_data.glyph;\n this.cds_select = this.model.renderer_select.data_source;\n this.cds_data = this.model.renderer_data.data_source;\n var _c = [this.glyph_data.xs.field, this.glyph_data.ys.field], xskey = _c[0], yskey = _c[1];\n this.xdata = this.cds_data.get_array(xskey)[0];\n this.ydataT = array_1.transpose(this.cds_data.get_array(yskey));\n this.selection_indices = [];\n this.connect(this.plot_view.frame.x_ranges[this.model.renderer_select.x_range_name].change, function () { return _this._resize_boxes_on_zoom(); });\n this.connect(this.cds_select.change, function () { return _this._update_data_selection(); });\n };\n Object.defineProperty(ParallelSelectionView.prototype, \"_box_width\", {\n get: function () {\n return this.xscale.invert(this.model.box_width) - this.xscale.invert(0);\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(ParallelSelectionView.prototype, \"_cds_select_keys\", {\n get: function () {\n var glyph_select = this.glyph_select;\n var _a = [glyph_select.x.field, glyph_select.y.field], xkey = _a[0], ykey = _a[1];\n var _b = [glyph_select.width.field, glyph_select.height.field], wkey = _b[0], hkey = _b[1];\n return { xkey: xkey, ykey: ykey, wkey: wkey, hkey: hkey };\n },\n enumerable: true,\n configurable: true\n });\n ParallelSelectionView.prototype._emit_cds_changes = function (cds, redraw, clear, emit) {\n if (redraw === void 0) { redraw = true; }\n if (clear === void 0) { clear = true; }\n if (emit === void 0) { emit = true; }\n if (clear)\n cds.selection_manager.clear();\n if (redraw)\n cds.change.emit();\n if (emit) {\n cds.data = cds.data;\n cds.properties.data.change.emit();\n }\n };\n ParallelSelectionView.prototype._box_paramaters = function (index) {\n var _a = this._cds_select_keys, xkey = _a.xkey, ykey = _a.ykey, wkey = _a.wkey, hkey = _a.hkey;\n var x = this.cds_select.get_array(xkey)[index];\n var y = this.cds_select.get_array(ykey)[index];\n var w = this.cds_select.get_array(wkey)[index];\n var h = this.cds_select.get_array(hkey)[index];\n return { x: x, y: y, w: w, h: h };\n };\n ParallelSelectionView.prototype._hit_test_boxes = function (sx, sy) {\n var nboxes = this.cds_select.get_length();\n if (nboxes != 0 && nboxes != null) {\n var _a = [this.xscale.invert(sx), this.yscale.invert(sy)], xtest = _a[0], ytest = _a[1];\n for (var i = 0; i < nboxes; i++) {\n var _b = this._box_paramaters(i), x = _b.x, y = _b.y, w = _b.w, h = _b.h;\n if (xtest >= (x - w / 2) && xtest <= x + w / 2 &&\n ytest >= (y - h / 2) && ytest <= y + h / 2) {\n return i;\n }\n }\n }\n return null;\n };\n ParallelSelectionView.prototype._resize_boxes_on_zoom = function () {\n //resize selection boxes when zooming to keep a constant (pixel) size\n var cds = this.cds_select;\n var array_width = cds.get_array(this.glyph_select.width.field);\n var new_width = this._box_width;\n array_width.forEach(function (_, i) { return array_width[i] = new_width; });\n this._emit_cds_changes(cds, true, false, false);\n };\n ParallelSelectionView.prototype._drag_start = function (ev) {\n //Save y position of the drag start\n if (this.ind_active_box != null) {\n this._base_point = [this.xscale.invert(ev.sx), this.yscale.invert(ev.sy)];\n this._base_box_parameters = this._box_paramaters(this.ind_active_box);\n }\n };\n ParallelSelectionView.prototype._update_box_ypos = function (index_box, delta_y) {\n if (this._base_box_parameters != null) {\n var cds = this.cds_select;\n var ykey = this._cds_select_keys.ykey;\n var _a = this._base_box_parameters, current_y = _a.y, h = _a.h;\n var new_y = current_y + delta_y;\n new_y = new_y - Math.max(0, (new_y + h / 2) - 1) - Math.min(0, (new_y - h / 2));\n cds.get_array(ykey)[index_box] = new_y;\n this._emit_cds_changes(cds, true, false, false);\n this._update_selection_indices(index_box, [new_y - h / 2, new_y + h / 2]);\n }\n };\n ParallelSelectionView.prototype._drag = function (ev) {\n if (this.ind_active_box != null && this._base_point != null) {\n var delta_y = this.yscale.invert(ev.sy) - this._base_point[1];\n this._update_box_ypos(this.ind_active_box, delta_y);\n }\n };\n ParallelSelectionView.prototype._drag_stop = function (_ev) {\n this._base_point = null;\n this._base_box_parameters = null;\n };\n ParallelSelectionView.prototype._pan_start = function (ev) {\n this.panning = true;\n switch (this.selection_mode) {\n case \"add\": {\n _super.prototype._pan_start.call(this, ev);\n break;\n }\n case \"drag\": {\n this._drag_start(ev);\n break;\n }\n case \"resize\": {\n break;\n }\n }\n };\n ParallelSelectionView.prototype._pan = function (ev) {\n switch (this.selection_mode) {\n case \"add\": {\n _super.prototype._pan.call(this, ev);\n break;\n }\n case \"drag\": {\n this._drag(ev);\n break;\n }\n case \"resize\": {\n break;\n }\n }\n };\n ParallelSelectionView.prototype._pan_end = function (ev) {\n switch (this.selection_mode) {\n case \"add\": {\n _super.prototype._pan_end.call(this, ev);\n break;\n }\n case \"drag\": {\n this._drag_stop(ev);\n break;\n }\n case \"resize\": {\n break;\n }\n }\n this.panning = false;\n };\n ParallelSelectionView.prototype._move = function (ev) {\n //Switch mode\n if (this.panning) {\n return;\n }\n this.ind_active_box = this._hit_test_boxes(ev.sx, ev.sy);\n if (this.ind_active_box != null) {\n this.selection_mode = \"drag\";\n }\n else {\n this.selection_mode = \"add\";\n }\n };\n ParallelSelectionView.prototype._doubletap = function (_ev) {\n var _this = this;\n //delete box on double tap\n if (this.ind_active_box != null) {\n this.cds_select.columns().forEach(function (key) {\n _this.cds_select.get_array(key).splice(_this.ind_active_box, 1);\n });\n this._delete_selection_indices(this.ind_active_box);\n this._emit_cds_changes(this.cds_select);\n }\n };\n ParallelSelectionView.prototype._keyup = function (ev) {\n var _this = this;\n if (ev.keyCode == dom_1.Keys.Esc) {\n var nelems_1 = this.cds_select.get_length();\n if (nelems_1 != null) {\n this.cds_select.columns().forEach(function (key) {\n _this.cds_select.get_array(key).splice(0, nelems_1);\n });\n this.selection_indices.splice(0, nelems_1);\n this._emit_cds_changes(this.cds_select);\n }\n this.plot_view.request_render();\n }\n };\n ParallelSelectionView.prototype._update_data_selection = function () {\n var selection_indices = [];\n if (this.selection_indices.length > 0) {\n var combined_selections = combineByKey('data_idx', this.selection_indices);\n selection_indices = array_1.intersection.apply(void 0, [array_1.union.apply(void 0, combined_selections[0].indices)].concat(combined_selections.slice(1).map(function (elem) { return array_1.union.apply(void 0, elem.indices); })));\n }\n this.cds_data.selected.indices = selection_indices;\n this.cds_data.change.emit();\n };\n ParallelSelectionView.prototype._make_selection_indices = function (indices, _a) {\n var _this = this;\n var _b;\n var y0 = _a[0], y1 = _a[1];\n (_b = this.selection_indices).push.apply(_b, indices.map(function (index) {\n return {\n data_idx: index,\n indices: find_indices_in(_this.ydataT[index], [y0, y1]),\n };\n }));\n };\n ParallelSelectionView.prototype._update_selection_indices = function (index, _a) {\n var y0 = _a[0], y1 = _a[1];\n this.selection_indices[index].indices = find_indices_in(this.ydataT[this.selection_indices[index].data_idx], [y0, y1]);\n };\n ParallelSelectionView.prototype._delete_selection_indices = function (index) {\n this.selection_indices.splice(index, 1);\n };\n ParallelSelectionView.prototype._make_box_select = function (xs, _a) {\n var _this = this;\n var y0 = _a[0], y1 = _a[1];\n y0 = Math.max(0, y0);\n y1 = Math.min(1, y1);\n var y = (y0 + y1) / 2.;\n var w = this._box_width;\n var h = y1 - y0;\n var _b = this._cds_select_keys, xkey = _b.xkey, ykey = _b.ykey, wkey = _b.wkey, hkey = _b.hkey;\n xs.forEach(function (x) {\n if (xkey)\n _this.cds_select.get_array(xkey).push(x);\n if (ykey)\n _this.cds_select.get_array(ykey).push(y);\n if (wkey)\n _this.cds_select.get_array(wkey).push(w);\n if (hkey)\n _this.cds_select.get_array(hkey).push(h);\n });\n this._emit_cds_changes(this.cds_select);\n };\n ParallelSelectionView.prototype._do_select = function (_a, _b, _final, _append) {\n var sx0 = _a[0], sx1 = _a[1];\n var sy0 = _b[0], sy1 = _b[1];\n if (_final === void 0) { _final = true; }\n if (_append === void 0) { _append = true; }\n // Get selection bbox in the data space\n var _c = this.xscale.r_invert(sx0, sx1), x0 = _c[0], x1 = _c[1];\n var _d = this.yscale.r_invert(sy0, sy1), y0 = _d[0], y1 = _d[1];\n var x_indices = find_indices_in(this.xdata, [x0, x1]);\n var xs = index_array(this.xdata, x_indices);\n this._make_selection_indices(x_indices, [y0, y1]);\n this._make_box_select(xs, [y0, y1]);\n };\n return ParallelSelectionView;\n }(box_select_tool_1.BoxSelectToolView));\n exports.ParallelSelectionView = ParallelSelectionView;\n var ParallelSelectionTool = /** @class */ (function (_super) {\n __extends(ParallelSelectionTool, _super);\n function ParallelSelectionTool() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n _this.tool_name = \"Parallel Selection\";\n //override event_type property define in BoxSelectTool\n _this.event_type = [\"tap\", \"pan\", \"move\"];\n return _this;\n }\n ParallelSelectionTool.initClass = function () {\n this.prototype.type = \"ParallelSelectionTool\";\n this.prototype.default_view = ParallelSelectionView;\n this.define({\n renderer_select: [p.Any],\n renderer_data: [p.Any],\n box_width: [p.Number, 30],\n });\n };\n return ParallelSelectionTool;\n }(box_select_tool_1.BoxSelectTool));\n exports.ParallelSelectionTool = ParallelSelectionTool;\n ParallelSelectionTool.initClass();\n\n }\n }, \"custom/main\");\n ;\n });\n\n },\n function(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n \n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }if (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n var cell = $(document.getElementById(\"4897\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "(function(root) {\n", - " function embed_document(root) {\n", - " \n", - " var docs_json = {\"06bbb144-6c77-4643-bce0-9a725c3d0ad9\":{\"roots\":{\"references\":[{\"attributes\":{\"children\":[{\"id\":\"4566\",\"type\":\"Column\"},{\"id\":\"4574\",\"type\":\"Column\"}]},\"id\":\"4575\",\"type\":\"Row\"},{\"attributes\":{},\"id\":\"1032\",\"type\":\"WheelZoomTool\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"1084\",\"type\":\"GroupFilter\"},{\"attributes\":{\"high\":-11.644708333333334,\"low\":-77.62476166666667,\"palette\":[\"#440154\",\"#440255\",\"#440357\",\"#450558\",\"#45065A\",\"#45085B\",\"#46095C\",\"#460B5E\",\"#460C5F\",\"#460E61\",\"#470F62\",\"#471163\",\"#471265\",\"#471466\",\"#471567\",\"#471669\",\"#47186A\",\"#48196B\",\"#481A6C\",\"#481C6E\",\"#481D6F\",\"#481E70\",\"#482071\",\"#482172\",\"#482273\",\"#482374\",\"#472575\",\"#472676\",\"#472777\",\"#472878\",\"#472A79\",\"#472B7A\",\"#472C7B\",\"#462D7C\",\"#462F7C\",\"#46307D\",\"#46317E\",\"#45327F\",\"#45347F\",\"#453580\",\"#453681\",\"#443781\",\"#443982\",\"#433A83\",\"#433B83\",\"#433C84\",\"#423D84\",\"#423E85\",\"#424085\",\"#414186\",\"#414286\",\"#404387\",\"#404487\",\"#3F4587\",\"#3F4788\",\"#3E4888\",\"#3E4989\",\"#3D4A89\",\"#3D4B89\",\"#3D4C89\",\"#3C4D8A\",\"#3C4E8A\",\"#3B508A\",\"#3B518A\",\"#3A528B\",\"#3A538B\",\"#39548B\",\"#39558B\",\"#38568B\",\"#38578C\",\"#37588C\",\"#37598C\",\"#365A8C\",\"#365B8C\",\"#355C8C\",\"#355D8C\",\"#345E8D\",\"#345F8D\",\"#33608D\",\"#33618D\",\"#32628D\",\"#32638D\",\"#31648D\",\"#31658D\",\"#31668D\",\"#30678D\",\"#30688D\",\"#2F698D\",\"#2F6A8D\",\"#2E6B8E\",\"#2E6C8E\",\"#2E6D8E\",\"#2D6E8E\",\"#2D6F8E\",\"#2C708E\",\"#2C718E\",\"#2C728E\",\"#2B738E\",\"#2B748E\",\"#2A758E\",\"#2A768E\",\"#2A778E\",\"#29788E\",\"#29798E\",\"#287A8E\",\"#287A8E\",\"#287B8E\",\"#277C8E\",\"#277D8E\",\"#277E8E\",\"#267F8E\",\"#26808E\",\"#26818E\",\"#25828E\",\"#25838D\",\"#24848D\",\"#24858D\",\"#24868D\",\"#23878D\",\"#23888D\",\"#23898D\",\"#22898D\",\"#228A8D\",\"#228B8D\",\"#218C8D\",\"#218D8C\",\"#218E8C\",\"#208F8C\",\"#20908C\",\"#20918C\",\"#1F928C\",\"#1F938B\",\"#1F948B\",\"#1F958B\",\"#1F968B\",\"#1E978A\",\"#1E988A\",\"#1E998A\",\"#1E998A\",\"#1E9A89\",\"#1E9B89\",\"#1E9C89\",\"#1E9D88\",\"#1E9E88\",\"#1E9F88\",\"#1EA087\",\"#1FA187\",\"#1FA286\",\"#1FA386\",\"#20A485\",\"#20A585\",\"#21A685\",\"#21A784\",\"#22A784\",\"#23A883\",\"#23A982\",\"#24AA82\",\"#25AB81\",\"#26AC81\",\"#27AD80\",\"#28AE7F\",\"#29AF7F\",\"#2AB07E\",\"#2BB17D\",\"#2CB17D\",\"#2EB27C\",\"#2FB37B\",\"#30B47A\",\"#32B57A\",\"#33B679\",\"#35B778\",\"#36B877\",\"#38B976\",\"#39B976\",\"#3BBA75\",\"#3DBB74\",\"#3EBC73\",\"#40BD72\",\"#42BE71\",\"#44BE70\",\"#45BF6F\",\"#47C06E\",\"#49C16D\",\"#4BC26C\",\"#4DC26B\",\"#4FC369\",\"#51C468\",\"#53C567\",\"#55C666\",\"#57C665\",\"#59C764\",\"#5BC862\",\"#5EC961\",\"#60C960\",\"#62CA5F\",\"#64CB5D\",\"#67CC5C\",\"#69CC5B\",\"#6BCD59\",\"#6DCE58\",\"#70CE56\",\"#72CF55\",\"#74D054\",\"#77D052\",\"#79D151\",\"#7CD24F\",\"#7ED24E\",\"#81D34C\",\"#83D34B\",\"#86D449\",\"#88D547\",\"#8BD546\",\"#8DD644\",\"#90D643\",\"#92D741\",\"#95D73F\",\"#97D83E\",\"#9AD83C\",\"#9DD93A\",\"#9FD938\",\"#A2DA37\",\"#A5DA35\",\"#A7DB33\",\"#AADB32\",\"#ADDC30\",\"#AFDC2E\",\"#B2DD2C\",\"#B5DD2B\",\"#B7DD29\",\"#BADE27\",\"#BDDE26\",\"#BFDF24\",\"#C2DF22\",\"#C5DF21\",\"#C7E01F\",\"#CAE01E\",\"#CDE01D\",\"#CFE11C\",\"#D2E11B\",\"#D4E11A\",\"#D7E219\",\"#DAE218\",\"#DCE218\",\"#DFE318\",\"#E1E318\",\"#E4E318\",\"#E7E419\",\"#E9E419\",\"#ECE41A\",\"#EEE51B\",\"#F1E51C\",\"#F3E51E\",\"#F6E61F\",\"#F8E621\",\"#FAE622\",\"#FDE724\"]},\"id\":\"1040\",\"type\":\"LinearColorMapper\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"1085\",\"type\":\"GroupFilter\"},{\"attributes\":{\"overlay\":{\"id\":\"1169\",\"type\":\"BoxAnnotation\"}},\"id\":\"1031\",\"type\":\"BoxZoomTool\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"2848\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1086\",\"type\":\"GroupFilter\"},{\"attributes\":{},\"id\":\"1030\",\"type\":\"SaveTool\"},{\"attributes\":{\"booleans\":[true,true]},\"id\":\"1087\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1084\",\"type\":\"GroupFilter\"},{\"id\":\"1085\",\"type\":\"GroupFilter\"},{\"id\":\"1086\",\"type\":\"GroupFilter\"},{\"id\":\"1087\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"}},\"id\":\"1088\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"1089\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"1090\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1091\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true]},\"id\":\"1092\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1089\",\"type\":\"GroupFilter\"},{\"id\":\"1090\",\"type\":\"GroupFilter\"},{\"id\":\"1091\",\"type\":\"GroupFilter\"},{\"id\":\"1092\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"}},\"id\":\"1093\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"3631\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"1094\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"1095\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1096\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true]},\"id\":\"1097\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1094\",\"type\":\"GroupFilter\"},{\"id\":\"1095\",\"type\":\"GroupFilter\"},{\"id\":\"1096\",\"type\":\"GroupFilter\"},{\"id\":\"1097\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"}},\"id\":\"1098\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"1099\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"1100\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1101\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"2863\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true]},\"id\":\"1102\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1099\",\"type\":\"GroupFilter\"},{\"id\":\"1100\",\"type\":\"GroupFilter\"},{\"id\":\"1101\",\"type\":\"GroupFilter\"},{\"id\":\"1102\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"}},\"id\":\"1103\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"1104\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2850\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"1105\",\"type\":\"GroupFilter\"},{\"attributes\":{},\"id\":\"1033\",\"type\":\"ResetTool\"},{\"attributes\":{\"filters\":[{\"id\":\"2903\",\"type\":\"GroupFilter\"},{\"id\":\"2904\",\"type\":\"GroupFilter\"},{\"id\":\"2905\",\"type\":\"GroupFilter\"},{\"id\":\"2906\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"}},\"id\":\"2907\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1106\",\"type\":\"GroupFilter\"},{\"attributes\":{\"active_drag\":\"auto\",\"active_inspect\":\"auto\",\"active_multi\":null,\"active_scroll\":\"auto\",\"active_tap\":\"auto\",\"tools\":[{\"id\":\"1030\",\"type\":\"SaveTool\"},{\"id\":\"1031\",\"type\":\"BoxZoomTool\"},{\"id\":\"1032\",\"type\":\"WheelZoomTool\"},{\"id\":\"1033\",\"type\":\"ResetTool\"},{\"id\":\"4552\",\"type\":\"HoverTool\"}]},\"id\":\"1034\",\"type\":\"Toolbar\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"2849\",\"type\":\"GroupFilter\"},{\"attributes\":{\"callback\":null,\"data\":{\"image\":[{\"__ndarray__\":\"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\",\"dtype\":\"float64\",\"shape\":[18,17]},{\"__ndarray__\":\"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\",\"dtype\":\"float64\",\"shape\":[18,17]},{\"__ndarray__\":\"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\",\"dtype\":\"float64\",\"shape\":[18,17]}]},\"selected\":{\"id\":\"1171\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1170\",\"type\":\"UnionRenderers\"}},\"id\":\"1041\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"booleans\":[true,true]},\"id\":\"1107\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1104\",\"type\":\"GroupFilter\"},{\"id\":\"1105\",\"type\":\"GroupFilter\"},{\"id\":\"1106\",\"type\":\"GroupFilter\"},{\"id\":\"1107\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"}},\"id\":\"1108\",\"type\":\"CDSView\"},{\"attributes\":{\"color_mapper\":{\"id\":\"1040\",\"type\":\"LinearColorMapper\"},\"dh\":{\"units\":\"data\",\"value\":3.4511366685537075},\"dw\":{\"units\":\"data\",\"value\":3.3930259095244972},\"image\":{\"field\":\"image\"},\"x\":{\"value\":-1.7825845552138326},\"y\":{\"value\":-1.594487369895019}},\"id\":\"1042\",\"type\":\"Image\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"1109\",\"type\":\"GroupFilter\"},{\"attributes\":{\"color_mapper\":{\"id\":\"1040\",\"type\":\"LinearColorMapper\"},\"dh\":{\"units\":\"data\",\"value\":3.4511366685537075},\"dw\":{\"units\":\"data\",\"value\":3.3930259095244972},\"image\":{\"field\":\"image\"},\"x\":{\"value\":-1.7825845552138326},\"y\":{\"value\":-1.594487369895019}},\"id\":\"1043\",\"type\":\"Image\"},{\"attributes\":{\"data_source\":{\"id\":\"1041\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1042\",\"type\":\"Image\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1043\",\"type\":\"Image\"},\"selection_glyph\":null,\"view\":{\"id\":\"1045\",\"type\":\"CDSView\"}},\"id\":\"1044\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"1110\",\"type\":\"GroupFilter\"},{\"attributes\":{\"source\":{\"id\":\"1041\",\"type\":\"ColumnDataSource\"}},\"id\":\"1045\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1111\",\"type\":\"GroupFilter\"},{\"attributes\":{\"callback\":null,\"data\":{\"image\":[{\"__ndarray__\":\"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\",\"dtype\":\"float64\",\"shape\":[18,17]},{\"__ndarray__\":\"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\",\"dtype\":\"float64\",\"shape\":[18,17]},{\"__ndarray__\":\"fKha+OfHJ8B8qFr458cnwHyoWvjnxyfAfKha+OfHJ8B8qFr458cnwHyoWvjnxyfAfKha+OfHJ8AsQO41F0onwI75kwuosjfAzSvEECYKPcCarjqFb+JLwC6IWxj8Z1PALohbGPxnU8AuiFsY/GdTwC6IWxj8Z1PALohbGPxnU8AuiFsY/GdTwHyoWvjnxyfAfKha+OfHJ8B8qFr458cnwHyoWvjnxyfAfKha+OfHJ8B8qFr458cnwHyoWvjnxyfALEDuNRdKJ8CO+ZMLqLI3wM0rxBAmCj3Amq46hW/iS8AuiFsY/GdTwC6IWxj8Z1PALohbGPxnU8AuiFsY/GdTwC6IWxj8Z1PALohbGPxnU8B8qFr458cnwHyoWvjnxyfAfKha+OfHJ8B8qFr458cnwHyoWvjnxyfAfKha+OfHJ8B8qFr458cnwCxA7jUXSifAjvmTC6iyN8DNK8QQJgo9wJquOoVv4kvALohbGPxnU8AuiFsY/GdTwC6IWxj8Z1PALohbGPxnU8AuiFsY/GdTwC6IWxj8Z1PAfKha+OfHJ8B8qFr458cnwHyoWvjnxyfAfKha+OfHJ8B8qFr458cnwHyoWvjnxyfAfKha+OfHJ8AsQO41F0onwI75kwuosjfAzSvEECYKPcCarjqFb+JLwC6IWxj8Z1PALohbGPxnU8AuiFsY/GdTwC6IWxj8Z1PALohbGPxnU8AuiFsY/GdTwHyoWvjnxyfAfKha+OfHJ8B8qFr458cnwHyoWvjnxyfAfKha+OfHJ8B8qFr458cnwHyoWvjnxyfALEDuNRdKJ8CO+ZMLqLI3wM0rxBAmCj3Amq46hW/iS8AuiFsY/GdTwC6IWxj8Z1PALohbGPxnU8AuiFsY/GdTwC6IWxj8Z1PALohbGPxnU8B8qFr458cnwHyoWvjnxyfAfKha+OfHJ8B8qFr458cnwHyoWvjnxyfAfKha+OfHJ8B8qFr458cnwCxA7jUXSifAjvmTC6iyN8DNK8QQJgo9wJquOoVv4kvALohbGPxnU8AuiFsY/GdTwC6IWxj8Z1PALohbGPxnU8AuiFsY/GdTwC6IWxj8Z1PAfKha+OfHJ8B8qFr458cnwHyoWvjnxyfAfKha+OfHJ8B8qFr458cnwHyoWvjnxyfAfKha+OfHJ8AsQO41F0onwI75kwuosjfAzSvEECYKPcCarjqF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\",\"dtype\":\"float64\",\"shape\":[18,17]}]},\"selected\":{\"id\":\"1173\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1172\",\"type\":\"UnionRenderers\"}},\"id\":\"1046\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"booleans\":[true,true]},\"id\":\"1112\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"color_mapper\":{\"id\":\"1040\",\"type\":\"LinearColorMapper\"},\"dh\":{\"units\":\"data\",\"value\":3.4511366685537075},\"dw\":{\"units\":\"data\",\"value\":3.3930259095244972},\"image\":{\"field\":\"image\"},\"x\":{\"value\":-1.7825845552138326},\"y\":{\"value\":-1.594487369895019}},\"id\":\"1047\",\"type\":\"Image\"},{\"attributes\":{\"filters\":[{\"id\":\"1109\",\"type\":\"GroupFilter\"},{\"id\":\"1110\",\"type\":\"GroupFilter\"},{\"id\":\"1111\",\"type\":\"GroupFilter\"},{\"id\":\"1112\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"}},\"id\":\"1113\",\"type\":\"CDSView\"},{\"attributes\":{\"color_mapper\":{\"id\":\"1040\",\"type\":\"LinearColorMapper\"},\"dh\":{\"units\":\"data\",\"value\":3.4511366685537075},\"dw\":{\"units\":\"data\",\"value\":3.3930259095244972},\"image\":{\"field\":\"image\"},\"x\":{\"value\":-1.7825845552138326},\"y\":{\"value\":-1.594487369895019}},\"id\":\"1048\",\"type\":\"Image\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1115\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1046\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1047\",\"type\":\"Image\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1048\",\"type\":\"Image\"},\"selection_glyph\":null,\"view\":{\"id\":\"1050\",\"type\":\"CDSView\"},\"visible\":false},\"id\":\"1049\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"source\":{\"id\":\"1046\",\"type\":\"ColumnDataSource\"}},\"id\":\"1050\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1116\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"3227\",\"type\":\"GroupFilter\"},{\"id\":\"3228\",\"type\":\"GroupFilter\"},{\"id\":\"3229\",\"type\":\"GroupFilter\"},{\"id\":\"3230\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"}},\"id\":\"3231\",\"type\":\"CDSView\"},{\"attributes\":{\"args\":{\"colormapper\":{\"id\":\"1040\",\"type\":\"LinearColorMapper\"},\"glyph0\":{\"id\":\"1044\",\"type\":\"GlyphRenderer\"},\"glyph1\":{\"id\":\"1049\",\"type\":\"GlyphRenderer\"}},\"code\":\"var len_labels = 2,glyphs = [ glyph0,glyph1],mins = [-72.27169666666666, -77.62476166666667],maxs = [-11.867716666666666, -11.644708333333334];\\n for (i = 0; i < len_labels; i++) {\\n if (cb_obj.active === i) {\\n // console.log('Setting to true: ' + i);\\n glyphs[i].visible = true;\\n colormapper.low = mins[i];\\n colormapper.high = maxs[i];\\n } else {\\n // console.log('Setting to false: ' + i);\\n glyphs[i].visible = false;\\n }\\n }\\n \"},\"id\":\"4562\",\"type\":\"CustomJS\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true]},\"id\":\"3270\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"20\"},\"id\":\"4072\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1305\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"3267\",\"type\":\"GroupFilter\"},{\"id\":\"3268\",\"type\":\"GroupFilter\"},{\"id\":\"3269\",\"type\":\"GroupFilter\"},{\"id\":\"3270\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"}},\"id\":\"3271\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3224\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true]},\"id\":\"1306\",\"type\":\"BooleanFilter\"},{\"attributes\":{},\"id\":\"3742\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"active\":0,\"callback\":{\"id\":\"4562\",\"type\":\"CustomJS\"},\"labels\":[\"combined\",\"dqn seq del\"]},\"id\":\"4563\",\"type\":\"RadioButtonGroup\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true]},\"id\":\"3225\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"3272\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"3217\",\"type\":\"GroupFilter\"},{\"id\":\"3218\",\"type\":\"GroupFilter\"},{\"id\":\"3219\",\"type\":\"GroupFilter\"},{\"id\":\"3220\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"}},\"id\":\"3221\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"3743\",\"type\":\"Selection\"},{\"attributes\":{\"text\":\"Data used to estimate contour-plot\"},\"id\":\"4564\",\"type\":\"Div\"},{\"attributes\":{\"filters\":[{\"id\":\"1303\",\"type\":\"GroupFilter\"},{\"id\":\"1304\",\"type\":\"GroupFilter\"},{\"id\":\"1305\",\"type\":\"GroupFilter\"},{\"id\":\"1306\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"}},\"id\":\"1307\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"3273\",\"type\":\"GroupFilter\"},{\"attributes\":{\"children\":[{\"id\":\"4554\",\"type\":\"Slider\"}]},\"id\":\"4565\",\"type\":\"WidgetBox\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"4071\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"1308\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3229\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3274\",\"type\":\"GroupFilter\"},{\"attributes\":{\"children\":[{\"id\":\"1011\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"id\":\"4565\",\"type\":\"WidgetBox\"}]},\"id\":\"4566\",\"type\":\"Column\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"3233\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true]},\"id\":\"3275\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"children\":[{\"id\":\"4557\",\"type\":\"Div\"}]},\"id\":\"4567\",\"type\":\"WidgetBox\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"1309\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"3222\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"3272\",\"type\":\"GroupFilter\"},{\"id\":\"3273\",\"type\":\"GroupFilter\"},{\"id\":\"3274\",\"type\":\"GroupFilter\"},{\"id\":\"3275\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"}},\"id\":\"3276\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"4075\",\"type\":\"GroupFilter\"},{\"attributes\":{\"children\":[{\"id\":\"4555\",\"type\":\"CheckboxButtonGroup\"}]},\"id\":\"4568\",\"type\":\"WidgetBox\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1310\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4073\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"children\":[{\"id\":\"4559\",\"type\":\"Button\"}],\"width\":100},\"id\":\"4569\",\"type\":\"WidgetBox\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3278\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"3222\",\"type\":\"GroupFilter\"},{\"id\":\"3223\",\"type\":\"GroupFilter\"},{\"id\":\"3224\",\"type\":\"GroupFilter\"},{\"id\":\"3225\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"}},\"id\":\"3226\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true]},\"id\":\"1311\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"3223\",\"type\":\"GroupFilter\"},{\"attributes\":{\"children\":[{\"id\":\"4561\",\"type\":\"Button\"}],\"width\":100},\"id\":\"4570\",\"type\":\"WidgetBox\"},{\"attributes\":{\"filters\":[{\"id\":\"1308\",\"type\":\"GroupFilter\"},{\"id\":\"1309\",\"type\":\"GroupFilter\"},{\"id\":\"1310\",\"type\":\"GroupFilter\"},{\"id\":\"1311\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"}},\"id\":\"1312\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"4051\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3279\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"4077\",\"type\":\"GroupFilter\"},{\"attributes\":{\"children\":[{\"id\":\"4569\",\"type\":\"WidgetBox\"},{\"id\":\"4570\",\"type\":\"WidgetBox\"}]},\"id\":\"4571\",\"type\":\"Row\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"1313\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"4076\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3278\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3279\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3221\",\"type\":\"CDSView\"}},\"id\":\"3280\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true]},\"id\":\"3220\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"4056\",\"type\":\"GroupFilter\"},{\"attributes\":{\"children\":[{\"id\":\"4564\",\"type\":\"Div\"}]},\"id\":\"4572\",\"type\":\"WidgetBox\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"3228\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"1314\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"4080\",\"type\":\"GroupFilter\"},{\"attributes\":{\"children\":[{\"id\":\"4563\",\"type\":\"RadioButtonGroup\"}]},\"id\":\"4573\",\"type\":\"WidgetBox\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3311\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true]},\"id\":\"3230\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3282\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1315\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"4070\",\"type\":\"GroupFilter\"},{\"attributes\":{\"children\":[{\"id\":\"4567\",\"type\":\"WidgetBox\"},{\"id\":\"4568\",\"type\":\"WidgetBox\"},{\"id\":\"4571\",\"type\":\"Row\"},{\"id\":\"4572\",\"type\":\"WidgetBox\"},{\"id\":\"4573\",\"type\":\"WidgetBox\"}]},\"id\":\"4574\",\"type\":\"Column\"},{\"attributes\":{\"filters\":[{\"id\":\"4065\",\"type\":\"GroupFilter\"},{\"id\":\"4066\",\"type\":\"GroupFilter\"},{\"id\":\"4067\",\"type\":\"GroupFilter\"},{\"id\":\"4068\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4069\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3234\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3283\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"3232\",\"type\":\"GroupFilter\"},{\"id\":\"3233\",\"type\":\"GroupFilter\"},{\"id\":\"3234\",\"type\":\"GroupFilter\"},{\"id\":\"3235\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"}},\"id\":\"3236\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true]},\"id\":\"1316\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3282\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3283\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3226\",\"type\":\"CDSView\"}},\"id\":\"3284\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"1313\",\"type\":\"GroupFilter\"},{\"id\":\"1314\",\"type\":\"GroupFilter\"},{\"id\":\"1315\",\"type\":\"GroupFilter\"},{\"id\":\"1316\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"}},\"id\":\"1317\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true]},\"id\":\"3235\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"4070\",\"type\":\"GroupFilter\"},{\"id\":\"4071\",\"type\":\"GroupFilter\"},{\"id\":\"4072\",\"type\":\"GroupFilter\"},{\"id\":\"4073\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4074\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"1318\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"3238\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3310\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3286\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3239\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"1319\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3287\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"3237\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1320\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4078\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3286\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3287\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3231\",\"type\":\"CDSView\"}},\"id\":\"3288\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true]},\"id\":\"3240\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"4050\",\"type\":\"GroupFilter\"},{\"id\":\"4051\",\"type\":\"GroupFilter\"},{\"id\":\"4052\",\"type\":\"GroupFilter\"},{\"id\":\"4053\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4054\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true]},\"id\":\"1321\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"4055\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1318\",\"type\":\"GroupFilter\"},{\"id\":\"1319\",\"type\":\"GroupFilter\"},{\"id\":\"1320\",\"type\":\"GroupFilter\"},{\"id\":\"1321\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"}},\"id\":\"1322\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3290\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"3237\",\"type\":\"GroupFilter\"},{\"id\":\"3238\",\"type\":\"GroupFilter\"},{\"id\":\"3239\",\"type\":\"GroupFilter\"},{\"id\":\"3240\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"}},\"id\":\"3241\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4053\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"1323\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"3242\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"4057\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3291\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"20\"},\"id\":\"4052\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"4075\",\"type\":\"GroupFilter\"},{\"id\":\"4076\",\"type\":\"GroupFilter\"},{\"id\":\"4077\",\"type\":\"GroupFilter\"},{\"id\":\"4078\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4079\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3244\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3290\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3291\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3236\",\"type\":\"CDSView\"}},\"id\":\"3292\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"1324\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true]},\"id\":\"3245\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1325\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3306\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3307\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3256\",\"type\":\"CDSView\"}},\"id\":\"3308\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4058\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3294\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true]},\"id\":\"1326\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"3243\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"4055\",\"type\":\"GroupFilter\"},{\"id\":\"4056\",\"type\":\"GroupFilter\"},{\"id\":\"4057\",\"type\":\"GroupFilter\"},{\"id\":\"4058\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4059\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true]},\"id\":\"1346\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1323\",\"type\":\"GroupFilter\"},{\"id\":\"1324\",\"type\":\"GroupFilter\"},{\"id\":\"1325\",\"type\":\"GroupFilter\"},{\"id\":\"1326\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"}},\"id\":\"1327\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3295\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"3232\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"4060\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3294\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3295\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3241\",\"type\":\"CDSView\"}},\"id\":\"3296\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"1328\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"3227\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"4061\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3307\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"1329\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3298\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"20\"},\"id\":\"4062\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1330\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3299\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"3242\",\"type\":\"GroupFilter\"},{\"id\":\"3243\",\"type\":\"GroupFilter\"},{\"id\":\"3244\",\"type\":\"GroupFilter\"},{\"id\":\"3245\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"}},\"id\":\"3246\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4063\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"booleans\":[true,true,true]},\"id\":\"1331\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"3247\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3298\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3299\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3246\",\"type\":\"CDSView\"}},\"id\":\"3300\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"4060\",\"type\":\"GroupFilter\"},{\"id\":\"4061\",\"type\":\"GroupFilter\"},{\"id\":\"4062\",\"type\":\"GroupFilter\"},{\"id\":\"4063\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4064\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"3248\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1328\",\"type\":\"GroupFilter\"},{\"id\":\"1329\",\"type\":\"GroupFilter\"},{\"id\":\"1330\",\"type\":\"GroupFilter\"},{\"id\":\"1331\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"}},\"id\":\"1332\",\"type\":\"CDSView\"},{\"attributes\":{\"filters\":[{\"id\":\"3247\",\"type\":\"GroupFilter\"},{\"id\":\"3248\",\"type\":\"GroupFilter\"},{\"id\":\"3249\",\"type\":\"GroupFilter\"},{\"id\":\"3250\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"}},\"id\":\"3251\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"3606\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"4065\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3306\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"1333\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3249\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3302\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"4066\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3303\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"1334\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true]},\"id\":\"3250\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"4067\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3302\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3303\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3251\",\"type\":\"CDSView\"}},\"id\":\"3304\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1335\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4068\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1959\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"1887\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1368\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1369\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1312\",\"type\":\"CDSView\"}},\"id\":\"1370\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"2186\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1958\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1959\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1910\",\"type\":\"CDSView\"}},\"id\":\"1960\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1888\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"1917\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"2185\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1589\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1918\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true]},\"id\":\"2188\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1372\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1893\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1962\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"2180\",\"type\":\"GroupFilter\"},{\"id\":\"2181\",\"type\":\"GroupFilter\"},{\"id\":\"2182\",\"type\":\"GroupFilter\"},{\"id\":\"2183\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"}},\"id\":\"2184\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true,true,true]},\"id\":\"1919\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1373\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"1892\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2187\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1963\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"1916\",\"type\":\"GroupFilter\"},{\"id\":\"1917\",\"type\":\"GroupFilter\"},{\"id\":\"1918\",\"type\":\"GroupFilter\"},{\"id\":\"1919\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"}},\"id\":\"1920\",\"type\":\"CDSView\"},{\"attributes\":{\"data_source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1372\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1373\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1317\",\"type\":\"CDSView\"}},\"id\":\"1374\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true]},\"id\":\"2193\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1962\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1963\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1915\",\"type\":\"CDSView\"}},\"id\":\"1964\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1922\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"2853\",\"type\":\"GroupFilter\"},{\"id\":\"2854\",\"type\":\"GroupFilter\"},{\"id\":\"2855\",\"type\":\"GroupFilter\"},{\"id\":\"2856\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"}},\"id\":\"2857\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"1592\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"1891\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true]},\"id\":\"2183\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2192\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1376\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"1886\",\"type\":\"GroupFilter\"},{\"id\":\"1887\",\"type\":\"GroupFilter\"},{\"id\":\"1888\",\"type\":\"GroupFilter\"},{\"id\":\"1889\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"}},\"id\":\"1890\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"2191\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1966\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1923\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"2869\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1377\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true]},\"id\":\"1889\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"2190\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1922\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1923\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1865\",\"type\":\"CDSView\"}},\"id\":\"1924\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1967\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"2629\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"data_source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1376\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1377\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1322\",\"type\":\"CDSView\"}},\"id\":\"1378\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"2185\",\"type\":\"GroupFilter\"},{\"id\":\"2186\",\"type\":\"GroupFilter\"},{\"id\":\"2187\",\"type\":\"GroupFilter\"},{\"id\":\"2188\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"}},\"id\":\"2189\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true,true,true]},\"id\":\"1894\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1966\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1967\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1920\",\"type\":\"CDSView\"}},\"id\":\"1968\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"2630\",\"type\":\"Selection\"},{\"attributes\":{\"filters\":[{\"id\":\"1891\",\"type\":\"GroupFilter\"},{\"id\":\"1892\",\"type\":\"GroupFilter\"},{\"id\":\"1893\",\"type\":\"GroupFilter\"},{\"id\":\"1894\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"}},\"id\":\"1895\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1955\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1926\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"1896\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"2210\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"2853\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1380\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2870\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1927\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1381\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1666\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1926\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1927\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1870\",\"type\":\"CDSView\"}},\"id\":\"1928\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"1897\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"2874\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1380\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1381\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1327\",\"type\":\"CDSView\"}},\"id\":\"1382\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"2190\",\"type\":\"GroupFilter\"},{\"id\":\"2191\",\"type\":\"GroupFilter\"},{\"id\":\"2192\",\"type\":\"GroupFilter\"},{\"id\":\"2193\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"}},\"id\":\"2194\",\"type\":\"CDSView\"},{\"attributes\":{\"filters\":[{\"id\":\"1896\",\"type\":\"GroupFilter\"},{\"id\":\"1897\",\"type\":\"GroupFilter\"},{\"id\":\"1898\",\"type\":\"GroupFilter\"},{\"id\":\"1899\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"}},\"id\":\"1900\",\"type\":\"CDSView\"},{\"attributes\":{\"data_source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1661\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1662\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1611\",\"type\":\"CDSView\"}},\"id\":\"1663\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1954\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"2878\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1930\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"2210\",\"type\":\"GroupFilter\"},{\"id\":\"2211\",\"type\":\"GroupFilter\"},{\"id\":\"2212\",\"type\":\"GroupFilter\"},{\"id\":\"2213\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"}},\"id\":\"2214\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"1901\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1384\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true]},\"id\":\"1899\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"2868\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1931\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"2215\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1385\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1898\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1930\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1931\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1875\",\"type\":\"CDSView\"}},\"id\":\"1932\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1384\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1385\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1332\",\"type\":\"CDSView\"}},\"id\":\"1386\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"2868\",\"type\":\"GroupFilter\"},{\"id\":\"2869\",\"type\":\"GroupFilter\"},{\"id\":\"2870\",\"type\":\"GroupFilter\"},{\"id\":\"2871\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"}},\"id\":\"2872\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1669\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"2873\",\"type\":\"GroupFilter\"},{\"id\":\"2874\",\"type\":\"GroupFilter\"},{\"id\":\"2875\",\"type\":\"GroupFilter\"},{\"id\":\"2876\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"}},\"id\":\"2877\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"1902\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1587\",\"type\":\"GroupFilter\"},{\"id\":\"1588\",\"type\":\"GroupFilter\"},{\"id\":\"1589\",\"type\":\"GroupFilter\"},{\"id\":\"1590\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"}},\"id\":\"1591\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1934\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"2171\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2197\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1388\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1903\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true]},\"id\":\"2198\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1935\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"2196\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"2201\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"2859\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1389\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"1906\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1934\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1935\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1880\",\"type\":\"CDSView\"}},\"id\":\"1936\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1388\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1389\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1337\",\"type\":\"CDSView\"}},\"id\":\"1390\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2875\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1665\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1666\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1616\",\"type\":\"CDSView\"}},\"id\":\"1667\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"1901\",\"type\":\"GroupFilter\"},{\"id\":\"1902\",\"type\":\"GroupFilter\"},{\"id\":\"1903\",\"type\":\"GroupFilter\"},{\"id\":\"1904\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"}},\"id\":\"1905\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"2195\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"2858\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1950\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1951\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1900\",\"type\":\"CDSView\"}},\"id\":\"1952\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"1588\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1662\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1938\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"2195\",\"type\":\"GroupFilter\"},{\"id\":\"2196\",\"type\":\"GroupFilter\"},{\"id\":\"2197\",\"type\":\"GroupFilter\"},{\"id\":\"2198\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"}},\"id\":\"2199\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true,true,true]},\"id\":\"1904\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1392\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1908\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"2175\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1939\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2177\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"2200\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true]},\"id\":\"2871\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1393\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2264\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"1861\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1938\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1939\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1885\",\"type\":\"CDSView\"}},\"id\":\"1940\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"1907\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true]},\"id\":\"1909\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"2176\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1392\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1393\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1342\",\"type\":\"CDSView\"}},\"id\":\"1394\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1987\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true]},\"id\":\"2203\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"2863\",\"type\":\"GroupFilter\"},{\"id\":\"2864\",\"type\":\"GroupFilter\"},{\"id\":\"2865\",\"type\":\"GroupFilter\"},{\"id\":\"2866\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"}},\"id\":\"2867\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"2864\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1951\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true]},\"id\":\"1590\",\"type\":\"BooleanFilter\"},{\"attributes\":{},\"id\":\"1988\",\"type\":\"Selection\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1942\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"1593\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"1912\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2202\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1396\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true]},\"id\":\"2213\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true]},\"id\":\"2876\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1943\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"1911\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1397\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"2200\",\"type\":\"GroupFilter\"},{\"id\":\"2201\",\"type\":\"GroupFilter\"},{\"id\":\"2202\",\"type\":\"GroupFilter\"},{\"id\":\"2203\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"}},\"id\":\"2204\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2855\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1942\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1943\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1890\",\"type\":\"CDSView\"}},\"id\":\"1944\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"1906\",\"type\":\"GroupFilter\"},{\"id\":\"1907\",\"type\":\"GroupFilter\"},{\"id\":\"1908\",\"type\":\"GroupFilter\"},{\"id\":\"1909\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"}},\"id\":\"1910\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true]},\"id\":\"2173\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2860\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1396\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1397\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1347\",\"type\":\"CDSView\"}},\"id\":\"1398\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"1866\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"2205\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"2180\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1950\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"1426\",\"type\":\"Selection\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"1862\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1665\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1946\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"1886\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"2206\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1400\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2865\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1670\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"1881\",\"type\":\"GroupFilter\"},{\"id\":\"1882\",\"type\":\"GroupFilter\"},{\"id\":\"1883\",\"type\":\"GroupFilter\"},{\"id\":\"1884\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"}},\"id\":\"1885\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1947\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"2181\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1401\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2207\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true]},\"id\":\"2866\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1946\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1947\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1895\",\"type\":\"CDSView\"}},\"id\":\"1948\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"2170\",\"type\":\"GroupFilter\"},{\"id\":\"2171\",\"type\":\"GroupFilter\"},{\"id\":\"2172\",\"type\":\"GroupFilter\"},{\"id\":\"2173\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"}},\"id\":\"2174\",\"type\":\"CDSView\"},{\"attributes\":{\"filters\":[{\"id\":\"2858\",\"type\":\"GroupFilter\"},{\"id\":\"2859\",\"type\":\"GroupFilter\"},{\"id\":\"2860\",\"type\":\"GroupFilter\"},{\"id\":\"2861\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"}},\"id\":\"2862\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true]},\"id\":\"2208\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1400\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1401\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1352\",\"type\":\"CDSView\"}},\"id\":\"1402\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"2175\",\"type\":\"GroupFilter\"},{\"id\":\"2176\",\"type\":\"GroupFilter\"},{\"id\":\"2177\",\"type\":\"GroupFilter\"},{\"id\":\"2178\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"}},\"id\":\"2179\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"2854\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1954\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1955\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1905\",\"type\":\"CDSView\"}},\"id\":\"1956\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"2205\",\"type\":\"GroupFilter\"},{\"id\":\"2206\",\"type\":\"GroupFilter\"},{\"id\":\"2207\",\"type\":\"GroupFilter\"},{\"id\":\"2208\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"}},\"id\":\"2209\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1913\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1911\",\"type\":\"GroupFilter\"},{\"id\":\"1912\",\"type\":\"GroupFilter\"},{\"id\":\"1913\",\"type\":\"GroupFilter\"},{\"id\":\"1914\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"}},\"id\":\"1915\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1425\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2172\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"1916\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"2170\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true]},\"id\":\"2178\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"2211\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1404\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true]},\"id\":\"1914\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2182\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1958\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2212\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true]},\"id\":\"2861\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1405\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true]},\"id\":\"2856\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2954\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2953\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2954\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2907\",\"type\":\"CDSView\"}},\"id\":\"2955\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1878\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true]},\"id\":\"1356\",\"type\":\"BooleanFilter\"},{\"attributes\":{},\"id\":\"1697\",\"type\":\"Selection\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"3253\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true]},\"id\":\"3260\",\"type\":\"BooleanFilter\"},{\"attributes\":{},\"id\":\"2980\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"1358\",\"type\":\"GroupFilter\"},{\"attributes\":{},\"id\":\"2981\",\"type\":\"Selection\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3259\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"3263\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true]},\"id\":\"3265\",\"type\":\"BooleanFilter\"},{\"attributes\":{},\"id\":\"4261\",\"type\":\"UnionRenderers\"},{\"attributes\":{},\"id\":\"4262\",\"type\":\"Selection\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3254\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"3262\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"3258\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"3252\",\"type\":\"GroupFilter\"},{\"id\":\"3253\",\"type\":\"GroupFilter\"},{\"id\":\"3254\",\"type\":\"GroupFilter\"},{\"id\":\"3255\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"}},\"id\":\"3256\",\"type\":\"CDSView\"},{\"attributes\":{\"filters\":[{\"id\":\"3257\",\"type\":\"GroupFilter\"},{\"id\":\"3258\",\"type\":\"GroupFilter\"},{\"id\":\"3259\",\"type\":\"GroupFilter\"},{\"id\":\"3260\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"}},\"id\":\"3261\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"3268\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1868\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"3262\",\"type\":\"GroupFilter\"},{\"id\":\"3263\",\"type\":\"GroupFilter\"},{\"id\":\"3264\",\"type\":\"GroupFilter\"},{\"id\":\"3265\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"}},\"id\":\"3266\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"3267\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3264\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"1876\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3269\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true]},\"id\":\"3255\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1669\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1670\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1621\",\"type\":\"CDSView\"}},\"id\":\"1671\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"3257\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"3611\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true]},\"id\":\"1361\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2593\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4148\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true]},\"id\":\"1336\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1155\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1156\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1108\",\"type\":\"CDSView\"}},\"id\":\"1157\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2909\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2910\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2852\",\"type\":\"CDSView\"}},\"id\":\"2911\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"axis_label\":\"MDS-Y\",\"axis_label_text_font_size\":{\"value\":\"15pt\"},\"formatter\":{\"id\":\"1167\",\"type\":\"BasicTickFormatter\"},\"major_label_text_font_size\":{\"value\":\"12pt\"},\"ticker\":{\"id\":\"1026\",\"type\":\"BasicTicker\"}},\"id\":\"1025\",\"type\":\"LinearAxis\"},{\"attributes\":{\"desired_num_ticks\":15},\"id\":\"1051\",\"type\":\"BasicTicker\"},{\"attributes\":{\"filters\":[{\"id\":\"1333\",\"type\":\"GroupFilter\"},{\"id\":\"1334\",\"type\":\"GroupFilter\"},{\"id\":\"1335\",\"type\":\"GroupFilter\"},{\"id\":\"1336\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"}},\"id\":\"1337\",\"type\":\"CDSView\"},{\"attributes\":{\"filters\":[{\"id\":\"1622\",\"type\":\"GroupFilter\"},{\"id\":\"1623\",\"type\":\"GroupFilter\"},{\"id\":\"1624\",\"type\":\"GroupFilter\"},{\"id\":\"1625\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"}},\"id\":\"1626\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2572\",\"type\":\"Scatter\"},{\"attributes\":{\"color_mapper\":{\"id\":\"1040\",\"type\":\"LinearColorMapper\"},\"formatter\":{\"id\":\"1164\",\"type\":\"BasicTickFormatter\"},\"label_standoff\":12,\"location\":[0,0],\"major_label_text_font_size\":{\"value\":\"12pt\"},\"ticker\":{\"id\":\"1051\",\"type\":\"BasicTicker\"}},\"id\":\"1052\",\"type\":\"ColorBar\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2942\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4149\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4148\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4149\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4034\",\"type\":\"CDSView\"}},\"id\":\"4150\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2573\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"1026\",\"type\":\"BasicTicker\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"1338\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1159\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2913\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"1627\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2572\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2573\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2518\",\"type\":\"CDSView\"}},\"id\":\"2574\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4200\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"1628\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3608\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1160\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2914\",\"type\":\"Scatter\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"red\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\"],\"origin\":[\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\"],\"p_delay\":[\"None\",\"None\",\"None\",\"None\",1,1,1,1,2,2,2,2,4,4],\"p_sequence_length\":[1,2,3,4,1,2,3,4,1,2,3,4,1,2],\"runs\":[1,1,1,1,1,1,1,1,1,1,1,1,1,1],\"size\":[12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0],\"type\":[\"Final Incumbent\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\"],\"x\":{\"__ndarray__\":\"9XycTryI4z8V1Y/pH4nVP33uZXS0Jq8/nYRVUx7zyL/jng7jxhThP6T+EOPF7tA/ZyIjRMDzOT9NoCikMQ/Pv52J5DpVYt4/vIle97OdyT9U/iO4yVyyv9fmb0ChoNS/bHPta/FD1z83ME5yQuCzPw==\",\"dtype\":\"float64\",\"shape\":[14]},\"y\":{\"__ndarray__\":\"mzBNdScfwr/cguHH3HPRv8eNZF3Badu/c7FyYAoG47/ygmwPQ8SivzX5O1I4IcS/mkKm6HCl078HiqO8Tmrev+mQWWh3ybc/XU2yO8n9oL+KgUkYMf7Hv/TTqU536ta/ePHIKFAr1z/sli0p0TnMPw==\",\"dtype\":\"float64\",\"shape\":[14]},\"zorder\":[\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\"]},\"selected\":{\"id\":\"3743\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"3742\",\"type\":\"UnionRenderers\"}},\"id\":\"1009\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2592\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4152\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"1054\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"1339\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1159\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1160\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1113\",\"type\":\"CDSView\"}},\"id\":\"1161\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2913\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2914\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2857\",\"type\":\"CDSView\"}},\"id\":\"2915\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1340\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2576\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4153\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"1055\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true]},\"id\":\"1630\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2941\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true]},\"id\":\"1341\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3638\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4152\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4153\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4039\",\"type\":\"CDSView\"}},\"id\":\"4154\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"1627\",\"type\":\"GroupFilter\"},{\"id\":\"1628\",\"type\":\"GroupFilter\"},{\"id\":\"1629\",\"type\":\"GroupFilter\"},{\"id\":\"1630\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"}},\"id\":\"1631\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2577\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1056\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1338\",\"type\":\"GroupFilter\"},{\"id\":\"1339\",\"type\":\"GroupFilter\"},{\"id\":\"1340\",\"type\":\"GroupFilter\"},{\"id\":\"1341\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"}},\"id\":\"1342\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2917\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"3612\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1677\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1678\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1631\",\"type\":\"CDSView\"}},\"id\":\"1679\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2576\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2577\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2523\",\"type\":\"CDSView\"}},\"id\":\"2578\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"dimension\":1,\"ticker\":{\"id\":\"1026\",\"type\":\"BasicTicker\"}},\"id\":\"1029\",\"type\":\"Grid\"},{\"attributes\":{\"callback\":null,\"end\":10,\"js_property_callbacks\":{\"change:value\":[{\"id\":\"4556\",\"type\":\"CustomJS\"}]},\"start\":1,\"title\":\"Until wallclocktime 21.90. Step no. \",\"value\":10},\"id\":\"4554\",\"type\":\"Slider\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1633\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2918\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true]},\"id\":\"1057\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1054\",\"type\":\"GroupFilter\"},{\"id\":\"1055\",\"type\":\"GroupFilter\"},{\"id\":\"1056\",\"type\":\"GroupFilter\"},{\"id\":\"1057\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"}},\"id\":\"1058\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4156\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"1343\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true]},\"id\":\"2851\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2917\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2918\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2862\",\"type\":\"CDSView\"}},\"id\":\"2919\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"3252\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3613\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1634\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2580\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4157\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"1059\",\"type\":\"GroupFilter\"},{\"attributes\":{\"ticker\":{\"id\":\"1021\",\"type\":\"BasicTicker\"}},\"id\":\"1024\",\"type\":\"Grid\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"1344\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3618\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1633\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1634\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1576\",\"type\":\"CDSView\"}},\"id\":\"1635\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4156\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4157\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4044\",\"type\":\"CDSView\"}},\"id\":\"4158\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2581\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1345\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2921\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"1021\",\"type\":\"BasicTicker\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"1060\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2580\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2581\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2528\",\"type\":\"CDSView\"}},\"id\":\"2582\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4196\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4197\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4094\",\"type\":\"CDSView\"}},\"id\":\"4198\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1678\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"3606\",\"type\":\"GroupFilter\"},{\"id\":\"3607\",\"type\":\"GroupFilter\"},{\"id\":\"3608\",\"type\":\"GroupFilter\"},{\"id\":\"3609\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"}},\"id\":\"3610\",\"type\":\"CDSView\"},{\"attributes\":{\"axis_label\":\"MDS-X\",\"axis_label_text_font_size\":{\"value\":\"15pt\"},\"formatter\":{\"id\":\"1165\",\"type\":\"BasicTickFormatter\"},\"major_label_text_font_size\":{\"value\":\"12pt\"},\"ticker\":{\"id\":\"1021\",\"type\":\"BasicTicker\"}},\"id\":\"1020\",\"type\":\"LinearAxis\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2922\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1061\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2588\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2589\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2538\",\"type\":\"CDSView\"}},\"id\":\"2590\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"1343\",\"type\":\"GroupFilter\"},{\"id\":\"1344\",\"type\":\"GroupFilter\"},{\"id\":\"1345\",\"type\":\"GroupFilter\"},{\"id\":\"1346\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"}},\"id\":\"1347\",\"type\":\"CDSView\"},{\"attributes\":{\"filters\":[{\"id\":\"1866\",\"type\":\"GroupFilter\"},{\"id\":\"1867\",\"type\":\"GroupFilter\"},{\"id\":\"1868\",\"type\":\"GroupFilter\"},{\"id\":\"1869\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"}},\"id\":\"1870\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1637\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2921\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2922\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2867\",\"type\":\"CDSView\"}},\"id\":\"2923\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4160\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true]},\"id\":\"1062\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2263\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2264\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2214\",\"type\":\"CDSView\"}},\"id\":\"2265\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1638\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2584\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4161\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2937\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2938\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2887\",\"type\":\"CDSView\"}},\"id\":\"2939\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"1059\",\"type\":\"GroupFilter\"},{\"id\":\"1060\",\"type\":\"GroupFilter\"},{\"id\":\"1061\",\"type\":\"GroupFilter\"},{\"id\":\"1062\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"}},\"id\":\"1063\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"1348\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1637\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1638\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1581\",\"type\":\"CDSView\"}},\"id\":\"1639\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4160\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4161\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4049\",\"type\":\"CDSView\"}},\"id\":\"4162\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2585\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"1696\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2925\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"1064\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"1349\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2584\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2585\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2533\",\"type\":\"CDSView\"}},\"id\":\"2586\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1018\",\"type\":\"LinearScale\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1677\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4197\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"1016\",\"type\":\"LinearScale\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2926\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"3616\",\"type\":\"GroupFilter\"},{\"id\":\"3617\",\"type\":\"GroupFilter\"},{\"id\":\"3618\",\"type\":\"GroupFilter\"},{\"id\":\"3619\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"}},\"id\":\"3620\",\"type\":\"CDSView\"},{\"attributes\":{\"data_source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2592\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2593\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2543\",\"type\":\"CDSView\"}},\"id\":\"2594\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1641\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4164\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"1065\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2925\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2926\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2872\",\"type\":\"CDSView\"}},\"id\":\"2927\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1350\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true]},\"id\":\"1351\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1642\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"3631\",\"type\":\"GroupFilter\"},{\"id\":\"3632\",\"type\":\"GroupFilter\"},{\"id\":\"3633\",\"type\":\"GroupFilter\"},{\"id\":\"3634\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"}},\"id\":\"3635\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4165\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1066\",\"type\":\"GroupFilter\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"red\",\"white\",\"white\"],\"origin\":[\"Random\",\"Random\",\"Random\"],\"p_delay\":[\"None\",\"None\",\"None\"],\"p_sequence_length\":[1,2,3],\"runs\":[1,1,1],\"size\":[12.0,12.0,12.0],\"type\":[\"Final Incumbent\",\"Candidate\",\"Candidate\"],\"x\":{\"__ndarray__\":\"9XycTryI4z8V1Y/pH4nVP33uZXS0Jq8/\",\"dtype\":\"float64\",\"shape\":[3]},\"y\":{\"__ndarray__\":\"mzBNdScfwr/cguHH3HPRv8eNZF3Badu/\",\"dtype\":\"float64\",\"shape\":[3]},\"zorder\":[\"0\",\"0\",\"0\"]},\"selected\":{\"id\":\"1426\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1425\",\"type\":\"UnionRenderers\"}},\"id\":\"1002\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"filters\":[{\"id\":\"1348\",\"type\":\"GroupFilter\"},{\"id\":\"1349\",\"type\":\"GroupFilter\"},{\"id\":\"1350\",\"type\":\"GroupFilter\"},{\"id\":\"1351\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"}},\"id\":\"1352\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2938\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1641\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1642\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1586\",\"type\":\"CDSView\"}},\"id\":\"1643\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4164\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4165\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4054\",\"type\":\"CDSView\"}},\"id\":\"4166\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2596\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true]},\"id\":\"1067\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2929\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"1353\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1873\",\"type\":\"GroupFilter\"},{\"attributes\":{\"callback\":null,\"end\":1.8566492986586884,\"start\":-1.594487369895019},\"id\":\"1014\",\"type\":\"Range1d\"},{\"attributes\":{\"filters\":[{\"id\":\"1064\",\"type\":\"GroupFilter\"},{\"id\":\"1065\",\"type\":\"GroupFilter\"},{\"id\":\"1066\",\"type\":\"GroupFilter\"},{\"id\":\"1067\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"}},\"id\":\"1068\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2597\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4196\",\"type\":\"Scatter\"},{\"attributes\":{\"callback\":null,\"end\":1.6104413543106646,\"start\":-1.7825845552138326},\"id\":\"1012\",\"type\":\"Range1d\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2930\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true]},\"id\":\"1864\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2596\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2597\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2548\",\"type\":\"CDSView\"}},\"id\":\"2598\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"1164\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1645\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4168\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2929\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2930\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2877\",\"type\":\"CDSView\"}},\"id\":\"2931\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"1069\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"1354\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1646\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4169\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"1165\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1355\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2937\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"3611\",\"type\":\"GroupFilter\"},{\"id\":\"3612\",\"type\":\"GroupFilter\"},{\"id\":\"3613\",\"type\":\"GroupFilter\"},{\"id\":\"3614\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"}},\"id\":\"3615\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"1070\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1871\",\"type\":\"GroupFilter\"},{\"id\":\"1872\",\"type\":\"GroupFilter\"},{\"id\":\"1873\",\"type\":\"GroupFilter\"},{\"id\":\"1874\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"}},\"id\":\"1875\",\"type\":\"CDSView\"},{\"attributes\":{\"background_fill_color\":{\"value\":null},\"below\":[{\"id\":\"1020\",\"type\":\"LinearAxis\"}],\"border_fill_color\":{\"value\":null},\"center\":[{\"id\":\"1024\",\"type\":\"Grid\"},{\"id\":\"1029\",\"type\":\"Grid\"}],\"left\":[{\"id\":\"1025\",\"type\":\"LinearAxis\"}],\"plot_height\":500,\"renderers\":[{\"id\":\"1044\",\"type\":\"GlyphRenderer\"},{\"id\":\"1049\",\"type\":\"GlyphRenderer\"},{\"id\":\"1117\",\"type\":\"GlyphRenderer\"},{\"id\":\"1121\",\"type\":\"GlyphRenderer\"},{\"id\":\"1125\",\"type\":\"GlyphRenderer\"},{\"id\":\"1129\",\"type\":\"GlyphRenderer\"},{\"id\":\"1133\",\"type\":\"GlyphRenderer\"},{\"id\":\"1137\",\"type\":\"GlyphRenderer\"},{\"id\":\"1141\",\"type\":\"GlyphRenderer\"},{\"id\":\"1145\",\"type\":\"GlyphRenderer\"},{\"id\":\"1149\",\"type\":\"GlyphRenderer\"},{\"id\":\"1153\",\"type\":\"GlyphRenderer\"},{\"id\":\"1157\",\"type\":\"GlyphRenderer\"},{\"id\":\"1161\",\"type\":\"GlyphRenderer\"},{\"id\":\"1366\",\"type\":\"GlyphRenderer\"},{\"id\":\"1370\",\"type\":\"GlyphRenderer\"},{\"id\":\"1374\",\"type\":\"GlyphRenderer\"},{\"id\":\"1378\",\"type\":\"GlyphRenderer\"},{\"id\":\"1382\",\"type\":\"GlyphRenderer\"},{\"id\":\"1386\",\"type\":\"GlyphRenderer\"},{\"id\":\"1390\",\"type\":\"GlyphRenderer\"},{\"id\":\"1394\",\"type\":\"GlyphRenderer\"},{\"id\":\"1398\",\"type\":\"GlyphRenderer\"},{\"id\":\"1402\",\"type\":\"GlyphRenderer\"},{\"id\":\"1406\",\"type\":\"GlyphRenderer\"},{\"id\":\"1410\",\"type\":\"GlyphRenderer\"},{\"id\":\"1635\",\"type\":\"GlyphRenderer\"},{\"id\":\"1639\",\"type\":\"GlyphRenderer\"},{\"id\":\"1643\",\"type\":\"GlyphRenderer\"},{\"id\":\"1647\",\"type\":\"GlyphRenderer\"},{\"id\":\"1651\",\"type\":\"GlyphRenderer\"},{\"id\":\"1655\",\"type\":\"GlyphRenderer\"},{\"id\":\"1659\",\"type\":\"GlyphRenderer\"},{\"id\":\"1663\",\"type\":\"GlyphRenderer\"},{\"id\":\"1667\",\"type\":\"GlyphRenderer\"},{\"id\":\"1671\",\"type\":\"GlyphRenderer\"},{\"id\":\"1675\",\"type\":\"GlyphRenderer\"},{\"id\":\"1679\",\"type\":\"GlyphRenderer\"},{\"id\":\"1924\",\"type\":\"GlyphRenderer\"},{\"id\":\"1928\",\"type\":\"GlyphRenderer\"},{\"id\":\"1932\",\"type\":\"GlyphRenderer\"},{\"id\":\"1936\",\"type\":\"GlyphRenderer\"},{\"id\":\"1940\",\"type\":\"GlyphRenderer\"},{\"id\":\"1944\",\"type\":\"GlyphRenderer\"},{\"id\":\"1948\",\"type\":\"GlyphRenderer\"},{\"id\":\"1952\",\"type\":\"GlyphRenderer\"},{\"id\":\"1956\",\"type\":\"GlyphRenderer\"},{\"id\":\"1960\",\"type\":\"GlyphRenderer\"},{\"id\":\"1964\",\"type\":\"GlyphRenderer\"},{\"id\":\"1968\",\"type\":\"GlyphRenderer\"},{\"id\":\"2233\",\"type\":\"GlyphRenderer\"},{\"id\":\"2237\",\"type\":\"GlyphRenderer\"},{\"id\":\"2241\",\"type\":\"GlyphRenderer\"},{\"id\":\"2245\",\"type\":\"GlyphRenderer\"},{\"id\":\"2249\",\"type\":\"GlyphRenderer\"},{\"id\":\"2253\",\"type\":\"GlyphRenderer\"},{\"id\":\"2257\",\"type\":\"GlyphRenderer\"},{\"id\":\"2261\",\"type\":\"GlyphRenderer\"},{\"id\":\"2265\",\"type\":\"GlyphRenderer\"},{\"id\":\"2269\",\"type\":\"GlyphRenderer\"},{\"id\":\"2273\",\"type\":\"GlyphRenderer\"},{\"id\":\"2277\",\"type\":\"GlyphRenderer\"},{\"id\":\"2562\",\"type\":\"GlyphRenderer\"},{\"id\":\"2566\",\"type\":\"GlyphRenderer\"},{\"id\":\"2570\",\"type\":\"GlyphRenderer\"},{\"id\":\"2574\",\"type\":\"GlyphRenderer\"},{\"id\":\"2578\",\"type\":\"GlyphRenderer\"},{\"id\":\"2582\",\"type\":\"GlyphRenderer\"},{\"id\":\"2586\",\"type\":\"GlyphRenderer\"},{\"id\":\"2590\",\"type\":\"GlyphRenderer\"},{\"id\":\"2594\",\"type\":\"GlyphRenderer\"},{\"id\":\"2598\",\"type\":\"GlyphRenderer\"},{\"id\":\"2602\",\"type\":\"GlyphRenderer\"},{\"id\":\"2606\",\"type\":\"GlyphRenderer\"},{\"id\":\"2911\",\"type\":\"GlyphRenderer\"},{\"id\":\"2915\",\"type\":\"GlyphRenderer\"},{\"id\":\"2919\",\"type\":\"GlyphRenderer\"},{\"id\":\"2923\",\"type\":\"GlyphRenderer\"},{\"id\":\"2927\",\"type\":\"GlyphRenderer\"},{\"id\":\"2931\",\"type\":\"GlyphRenderer\"},{\"id\":\"2935\",\"type\":\"GlyphRenderer\"},{\"id\":\"2939\",\"type\":\"GlyphRenderer\"},{\"id\":\"2943\",\"type\":\"GlyphRenderer\"},{\"id\":\"2947\",\"type\":\"GlyphRenderer\"},{\"id\":\"2951\",\"type\":\"GlyphRenderer\"},{\"id\":\"2955\",\"type\":\"GlyphRenderer\"},{\"id\":\"3280\",\"type\":\"GlyphRenderer\"},{\"id\":\"3284\",\"type\":\"GlyphRenderer\"},{\"id\":\"3288\",\"type\":\"GlyphRenderer\"},{\"id\":\"3292\",\"type\":\"GlyphRenderer\"},{\"id\":\"3296\",\"type\":\"GlyphRenderer\"},{\"id\":\"3300\",\"type\":\"GlyphRenderer\"},{\"id\":\"3304\",\"type\":\"GlyphRenderer\"},{\"id\":\"3308\",\"type\":\"GlyphRenderer\"},{\"id\":\"3312\",\"type\":\"GlyphRenderer\"},{\"id\":\"3316\",\"type\":\"GlyphRenderer\"},{\"id\":\"3320\",\"type\":\"GlyphRenderer\"},{\"id\":\"3324\",\"type\":\"GlyphRenderer\"},{\"id\":\"3669\",\"type\":\"GlyphRenderer\"},{\"id\":\"3673\",\"type\":\"GlyphRenderer\"},{\"id\":\"3677\",\"type\":\"GlyphRenderer\"},{\"id\":\"3681\",\"type\":\"GlyphRenderer\"},{\"id\":\"3685\",\"type\":\"GlyphRenderer\"},{\"id\":\"3689\",\"type\":\"GlyphRenderer\"},{\"id\":\"3693\",\"type\":\"GlyphRenderer\"},{\"id\":\"3697\",\"type\":\"GlyphRenderer\"},{\"id\":\"3701\",\"type\":\"GlyphRenderer\"},{\"id\":\"3705\",\"type\":\"GlyphRenderer\"},{\"id\":\"3709\",\"type\":\"GlyphRenderer\"},{\"id\":\"3713\",\"type\":\"GlyphRenderer\"},{\"id\":\"4138\",\"type\":\"GlyphRenderer\"},{\"id\":\"4142\",\"type\":\"GlyphRenderer\"},{\"id\":\"4146\",\"type\":\"GlyphRenderer\"},{\"id\":\"4150\",\"type\":\"GlyphRenderer\"},{\"id\":\"4154\",\"type\":\"GlyphRenderer\"},{\"id\":\"4158\",\"type\":\"GlyphRenderer\"},{\"id\":\"4162\",\"type\":\"GlyphRenderer\"},{\"id\":\"4166\",\"type\":\"GlyphRenderer\"},{\"id\":\"4170\",\"type\":\"GlyphRenderer\"},{\"id\":\"4174\",\"type\":\"GlyphRenderer\"},{\"id\":\"4178\",\"type\":\"GlyphRenderer\"},{\"id\":\"4182\",\"type\":\"GlyphRenderer\"},{\"id\":\"4186\",\"type\":\"GlyphRenderer\"},{\"id\":\"4190\",\"type\":\"GlyphRenderer\"},{\"id\":\"4194\",\"type\":\"GlyphRenderer\"},{\"id\":\"4198\",\"type\":\"GlyphRenderer\"},{\"id\":\"4202\",\"type\":\"GlyphRenderer\"},{\"id\":\"4206\",\"type\":\"GlyphRenderer\"},{\"id\":\"4210\",\"type\":\"GlyphRenderer\"},{\"id\":\"4214\",\"type\":\"GlyphRenderer\"},{\"id\":\"4218\",\"type\":\"GlyphRenderer\"},{\"id\":\"4222\",\"type\":\"GlyphRenderer\"},{\"id\":\"4226\",\"type\":\"GlyphRenderer\"},{\"id\":\"4230\",\"type\":\"GlyphRenderer\"}],\"right\":[{\"id\":\"1052\",\"type\":\"ColorBar\"}],\"title\":{\"id\":\"1039\",\"type\":\"Title\"},\"toolbar\":{\"id\":\"1034\",\"type\":\"Toolbar\"},\"x_range\":{\"id\":\"1012\",\"type\":\"Range1d\"},\"x_scale\":{\"id\":\"1016\",\"type\":\"LinearScale\"},\"y_range\":{\"id\":\"1014\",\"type\":\"Range1d\"},\"y_scale\":{\"id\":\"1018\",\"type\":\"LinearScale\"}},\"id\":\"1011\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"attributes\":{\"data_source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1645\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1646\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1591\",\"type\":\"CDSView\"}},\"id\":\"1647\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4168\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4169\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4059\",\"type\":\"CDSView\"}},\"id\":\"4170\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2600\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2933\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"1167\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"filters\":[{\"id\":\"1876\",\"type\":\"GroupFilter\"},{\"id\":\"1877\",\"type\":\"GroupFilter\"},{\"id\":\"1878\",\"type\":\"GroupFilter\"},{\"id\":\"1879\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"}},\"id\":\"1880\",\"type\":\"CDSView\"},{\"attributes\":{\"data_source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1673\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1674\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1626\",\"type\":\"CDSView\"}},\"id\":\"1675\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"1353\",\"type\":\"GroupFilter\"},{\"id\":\"1354\",\"type\":\"GroupFilter\"},{\"id\":\"1355\",\"type\":\"GroupFilter\"},{\"id\":\"1356\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"}},\"id\":\"1357\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2601\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2934\",\"type\":\"Scatter\"},{\"attributes\":{\"bottom_units\":\"screen\",\"fill_alpha\":{\"value\":0.5},\"fill_color\":{\"value\":\"lightgrey\"},\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":{\"value\":1.0},\"line_color\":{\"value\":\"black\"},\"line_dash\":[4,4],\"line_width\":{\"value\":2},\"render_mode\":\"css\",\"right_units\":\"screen\",\"top_units\":\"screen\"},\"id\":\"1169\",\"type\":\"BoxAnnotation\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1071\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1861\",\"type\":\"GroupFilter\"},{\"id\":\"1862\",\"type\":\"GroupFilter\"},{\"id\":\"1863\",\"type\":\"GroupFilter\"},{\"id\":\"1864\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1004\",\"type\":\"ColumnDataSource\"}},\"id\":\"1865\",\"type\":\"CDSView\"},{\"attributes\":{\"data_source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2600\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2601\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2553\",\"type\":\"CDSView\"}},\"id\":\"2602\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1649\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4172\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2933\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2934\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2882\",\"type\":\"CDSView\"}},\"id\":\"2935\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"1069\",\"type\":\"GroupFilter\"},{\"id\":\"1070\",\"type\":\"GroupFilter\"},{\"id\":\"1071\",\"type\":\"GroupFilter\"},{\"id\":\"1072\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"}},\"id\":\"1073\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"1170\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1650\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4173\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"1171\",\"type\":\"Selection\"},{\"attributes\":{\"booleans\":[true,true,true,true,true]},\"id\":\"1869\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"text\":\"\",\"text_font_size\":{\"value\":\"15pt\"}},\"id\":\"1039\",\"type\":\"Title\"},{\"attributes\":{\"data_source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2941\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2942\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2892\",\"type\":\"CDSView\"}},\"id\":\"2943\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"1074\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1649\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1650\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1596\",\"type\":\"CDSView\"}},\"id\":\"1651\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4172\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4173\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4064\",\"type\":\"CDSView\"}},\"id\":\"4174\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2604\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"1172\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"1359\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1360\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true]},\"id\":\"1879\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4192\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4193\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4089\",\"type\":\"CDSView\"}},\"id\":\"4194\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1674\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2605\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"3621\",\"type\":\"GroupFilter\"},{\"id\":\"3622\",\"type\":\"GroupFilter\"},{\"id\":\"3623\",\"type\":\"GroupFilter\"},{\"id\":\"3624\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"}},\"id\":\"3625\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2945\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"1173\",\"type\":\"Selection\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"1075\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2604\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2605\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2558\",\"type\":\"CDSView\"}},\"id\":\"2606\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1653\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4176\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"1174\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"filters\":[{\"id\":\"1358\",\"type\":\"GroupFilter\"},{\"id\":\"1359\",\"type\":\"GroupFilter\"},{\"id\":\"1360\",\"type\":\"GroupFilter\"},{\"id\":\"1361\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"}},\"id\":\"1362\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2946\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1076\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1654\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4177\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"1175\",\"type\":\"Selection\"},{\"attributes\":{\"booleans\":[true,true]},\"id\":\"1077\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2945\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2946\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2897\",\"type\":\"CDSView\"}},\"id\":\"2947\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"booleans\":[true,true,true,true,true]},\"id\":\"1884\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"3627\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1653\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1654\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1601\",\"type\":\"CDSView\"}},\"id\":\"1655\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4176\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4177\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4069\",\"type\":\"CDSView\"}},\"id\":\"4178\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"1074\",\"type\":\"GroupFilter\"},{\"id\":\"1075\",\"type\":\"GroupFilter\"},{\"id\":\"1076\",\"type\":\"GroupFilter\"},{\"id\":\"1077\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"}},\"id\":\"1078\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1364\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"1303\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"1304\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"3218\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1673\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4193\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"1079\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3628\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1365\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2949\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"3629\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1657\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4180\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1364\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1365\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1307\",\"type\":\"CDSView\"}},\"id\":\"1366\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2950\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"3626\",\"type\":\"GroupFilter\"},{\"id\":\"3627\",\"type\":\"GroupFilter\"},{\"id\":\"3628\",\"type\":\"GroupFilter\"},{\"id\":\"3629\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"}},\"id\":\"3630\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1658\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4181\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"1080\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true]},\"id\":\"1874\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2949\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2950\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2902\",\"type\":\"CDSView\"}},\"id\":\"2951\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1081\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"1572\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1657\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1658\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1606\",\"type\":\"CDSView\"}},\"id\":\"1659\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4180\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4181\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4074\",\"type\":\"CDSView\"}},\"id\":\"4182\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"1867\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"1872\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1368\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true]},\"id\":\"1082\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"1871\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4192\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"3632\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1079\",\"type\":\"GroupFilter\"},{\"id\":\"1080\",\"type\":\"GroupFilter\"},{\"id\":\"1081\",\"type\":\"GroupFilter\"},{\"id\":\"1082\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"}},\"id\":\"1083\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1369\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2953\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"1881\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"2530\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4023\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"4081\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1404\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1405\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1357\",\"type\":\"CDSView\"}},\"id\":\"1406\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"4030\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2536\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"20\"},\"id\":\"4082\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4083\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1408\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"4080\",\"type\":\"GroupFilter\"},{\"id\":\"4081\",\"type\":\"GroupFilter\"},{\"id\":\"4082\",\"type\":\"GroupFilter\"},{\"id\":\"4083\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4084\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1409\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"2535\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"4085\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1002\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1408\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1409\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1362\",\"type\":\"CDSView\"}},\"id\":\"1410\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2511\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"4031\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"4045\",\"type\":\"GroupFilter\"},{\"id\":\"4046\",\"type\":\"GroupFilter\"},{\"id\":\"4047\",\"type\":\"GroupFilter\"},{\"id\":\"4048\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4049\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"4086\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"4050\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"4087\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2531\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"2534\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4088\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"4085\",\"type\":\"GroupFilter\"},{\"id\":\"4086\",\"type\":\"GroupFilter\"},{\"id\":\"4087\",\"type\":\"GroupFilter\"},{\"id\":\"4088\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4089\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true]},\"id\":\"2532\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"20\"},\"id\":\"4022\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4028\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"4090\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"3619\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"2514\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"4025\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"4091\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"4020\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"20\"},\"id\":\"4092\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"3637\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"4020\",\"type\":\"GroupFilter\"},{\"id\":\"4021\",\"type\":\"GroupFilter\"},{\"id\":\"4022\",\"type\":\"GroupFilter\"},{\"id\":\"4023\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4024\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true]},\"id\":\"2517\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"2509\",\"type\":\"GroupFilter\"},{\"id\":\"2510\",\"type\":\"GroupFilter\"},{\"id\":\"2511\",\"type\":\"GroupFilter\"},{\"id\":\"2512\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"}},\"id\":\"2513\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4093\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"red\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"orange\",\"white\",\"white\",\"white\",\"white\",\"white\"],\"origin\":[\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\"],\"p_delay\":[\"None\",\"None\",\"None\",\"None\",1,1,1,1,2,2,2,2,4,4,4,4,8,8,8,8],\"p_sequence_length\":[1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4],\"runs\":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],\"size\":[12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,36.0,12.0,12.0,12.0,12.0,12.0],\"type\":[\"Final Incumbent\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Default\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\"],\"x\":{\"__ndarray__\":\"9XycTryI4z8V1Y/pH4nVP33uZXS0Jq8/nYRVUx7zyL/jng7jxhThP6T+EOPF7tA/ZyIjRMDzOT9NoCikMQ/Pv52J5DpVYt4/vIle97OdyT9U/iO4yVyyv9fmb0ChoNS/bHPta/FD1z83ME5yQuCzP6CN+1CCs8y/eNa9Cfav37+8/kuUsG+2P00m6FDdzca/LRUVBt7n37+U8N/D7grpvw==\",\"dtype\":\"float64\",\"shape\":[20]},\"y\":{\"__ndarray__\":\"mzBNdScfwr/cguHH3HPRv8eNZF3Badu/c7FyYAoG47/ygmwPQ8SivzX5O1I4IcS/mkKm6HCl078HiqO8Tmrev+mQWWh3ybc/XU2yO8n9oL+KgUkYMf7Hv/TTqU536ta/ePHIKFAr1z/sli0p0TnMP82toUqzZ6k/jc+90/Xiv79FLDzKq2nrP/fU5FUHweU/ABKfywWy3z9fTLA7OAXXPw==\",\"dtype\":\"float64\",\"shape\":[20]},\"zorder\":[\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"20\",\"0\",\"0\",\"0\",\"0\",\"0\"]},\"selected\":{\"id\":\"4262\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"4261\",\"type\":\"UnionRenderers\"}},\"id\":\"1010\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"filters\":[{\"id\":\"4090\",\"type\":\"GroupFilter\"},{\"id\":\"4091\",\"type\":\"GroupFilter\"},{\"id\":\"4092\",\"type\":\"GroupFilter\"},{\"id\":\"4093\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4094\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"2505\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true]},\"id\":\"2507\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"2504\",\"type\":\"GroupFilter\"},{\"id\":\"2505\",\"type\":\"GroupFilter\"},{\"id\":\"2506\",\"type\":\"GroupFilter\"},{\"id\":\"2507\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"}},\"id\":\"2508\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"20\"},\"id\":\"4032\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"4095\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2516\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"4025\",\"type\":\"GroupFilter\"},{\"id\":\"4026\",\"type\":\"GroupFilter\"},{\"id\":\"4027\",\"type\":\"GroupFilter\"},{\"id\":\"4028\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4029\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2506\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"4021\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"4096\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4033\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"3636\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1574\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"4026\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"4097\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"1578\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"2515\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4048\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1582\",\"type\":\"GroupFilter\"},{\"id\":\"1583\",\"type\":\"GroupFilter\"},{\"id\":\"1584\",\"type\":\"GroupFilter\"},{\"id\":\"1585\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"}},\"id\":\"1586\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2521\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4098\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1661\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"4015\",\"type\":\"GroupFilter\"},{\"id\":\"4016\",\"type\":\"GroupFilter\"},{\"id\":\"4017\",\"type\":\"GroupFilter\"},{\"id\":\"4018\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4019\",\"type\":\"CDSView\"},{\"attributes\":{\"filters\":[{\"id\":\"4095\",\"type\":\"GroupFilter\"},{\"id\":\"4096\",\"type\":\"GroupFilter\"},{\"id\":\"4097\",\"type\":\"GroupFilter\"},{\"id\":\"4098\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4099\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"2520\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"4027\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"4030\",\"type\":\"GroupFilter\"},{\"id\":\"4031\",\"type\":\"GroupFilter\"},{\"id\":\"4032\",\"type\":\"GroupFilter\"},{\"id\":\"4033\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4034\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"4100\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"1882\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"2519\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"4035\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"4101\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"2514\",\"type\":\"GroupFilter\"},{\"id\":\"2515\",\"type\":\"GroupFilter\"},{\"id\":\"2516\",\"type\":\"GroupFilter\"},{\"id\":\"2517\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"}},\"id\":\"2518\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true,true]},\"id\":\"1580\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"4036\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"20\"},\"id\":\"4102\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"1582\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true]},\"id\":\"2512\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true]},\"id\":\"2522\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"4037\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4103\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true]},\"id\":\"1575\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"2529\",\"type\":\"GroupFilter\"},{\"id\":\"2530\",\"type\":\"GroupFilter\"},{\"id\":\"2531\",\"type\":\"GroupFilter\"},{\"id\":\"2532\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"}},\"id\":\"2533\",\"type\":\"CDSView\"},{\"attributes\":{\"filters\":[{\"id\":\"4100\",\"type\":\"GroupFilter\"},{\"id\":\"4101\",\"type\":\"GroupFilter\"},{\"id\":\"4102\",\"type\":\"GroupFilter\"},{\"id\":\"4103\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4104\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4038\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1577\",\"type\":\"GroupFilter\"},{\"id\":\"1578\",\"type\":\"GroupFilter\"},{\"id\":\"1579\",\"type\":\"GroupFilter\"},{\"id\":\"1580\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"}},\"id\":\"1581\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"2510\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"4035\",\"type\":\"GroupFilter\"},{\"id\":\"4036\",\"type\":\"GroupFilter\"},{\"id\":\"4037\",\"type\":\"GroupFilter\"},{\"id\":\"4038\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4039\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1579\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"4105\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"2509\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"1877\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3648\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"1573\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"4040\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"4106\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"3654\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true]},\"id\":\"1585\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"4041\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"4107\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"2519\",\"type\":\"GroupFilter\"},{\"id\":\"2520\",\"type\":\"GroupFilter\"},{\"id\":\"2521\",\"type\":\"GroupFilter\"},{\"id\":\"2522\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"}},\"id\":\"2523\",\"type\":\"CDSView\"},{\"attributes\":{\"filters\":[{\"id\":\"2524\",\"type\":\"GroupFilter\"},{\"id\":\"2525\",\"type\":\"GroupFilter\"},{\"id\":\"2526\",\"type\":\"GroupFilter\"},{\"id\":\"2527\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"}},\"id\":\"2528\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"20\"},\"id\":\"4042\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4108\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"1587\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"4105\",\"type\":\"GroupFilter\"},{\"id\":\"4106\",\"type\":\"GroupFilter\"},{\"id\":\"4107\",\"type\":\"GroupFilter\"},{\"id\":\"4108\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4109\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"2529\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4043\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"4040\",\"type\":\"GroupFilter\"},{\"id\":\"4041\",\"type\":\"GroupFilter\"},{\"id\":\"4042\",\"type\":\"GroupFilter\"},{\"id\":\"4043\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4044\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2526\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"4110\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1584\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"3634\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"4045\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"1583\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"4111\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"2524\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"1572\",\"type\":\"GroupFilter\"},{\"id\":\"1573\",\"type\":\"GroupFilter\"},{\"id\":\"1574\",\"type\":\"GroupFilter\"},{\"id\":\"1575\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"}},\"id\":\"1576\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true]},\"id\":\"1072\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"4046\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"20\"},\"id\":\"4112\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"1577\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true]},\"id\":\"2527\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"4047\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4113\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"2525\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3310\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3311\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3261\",\"type\":\"CDSView\"}},\"id\":\"3312\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true]},\"id\":\"2537\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"3649\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1115\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1116\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1058\",\"type\":\"CDSView\"}},\"id\":\"1117\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3684\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"1597\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"2534\",\"type\":\"GroupFilter\"},{\"id\":\"2535\",\"type\":\"GroupFilter\"},{\"id\":\"2536\",\"type\":\"GroupFilter\"},{\"id\":\"2537\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"}},\"id\":\"2538\",\"type\":\"CDSView\"},{\"attributes\":{\"filters\":[{\"id\":\"3646\",\"type\":\"GroupFilter\"},{\"id\":\"3647\",\"type\":\"GroupFilter\"},{\"id\":\"3648\",\"type\":\"GroupFilter\"},{\"id\":\"3649\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"}},\"id\":\"3650\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"2216\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3683\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3684\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3630\",\"type\":\"CDSView\"}},\"id\":\"3685\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"1592\",\"type\":\"GroupFilter\"},{\"id\":\"1593\",\"type\":\"GroupFilter\"},{\"id\":\"1594\",\"type\":\"GroupFilter\"},{\"id\":\"1595\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"}},\"id\":\"1596\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2217\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3314\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"1598\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"2539\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"3651\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1119\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3700\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true]},\"id\":\"2218\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3315\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1120\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"2215\",\"type\":\"GroupFilter\"},{\"id\":\"2216\",\"type\":\"GroupFilter\"},{\"id\":\"2217\",\"type\":\"GroupFilter\"},{\"id\":\"2218\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"}},\"id\":\"2219\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3687\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3314\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3315\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3266\",\"type\":\"CDSView\"}},\"id\":\"3316\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1599\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"2540\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"3652\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1119\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1120\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1063\",\"type\":\"CDSView\"}},\"id\":\"1121\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3688\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"2220\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true]},\"id\":\"1600\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2541\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"3646\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3653\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3687\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3688\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3635\",\"type\":\"CDSView\"}},\"id\":\"3689\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"1597\",\"type\":\"GroupFilter\"},{\"id\":\"1598\",\"type\":\"GroupFilter\"},{\"id\":\"1599\",\"type\":\"GroupFilter\"},{\"id\":\"1600\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"}},\"id\":\"1601\",\"type\":\"CDSView\"},{\"attributes\":{\"filters\":[{\"id\":\"3636\",\"type\":\"GroupFilter\"},{\"id\":\"3637\",\"type\":\"GroupFilter\"},{\"id\":\"3638\",\"type\":\"GroupFilter\"},{\"id\":\"3639\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"}},\"id\":\"3640\",\"type\":\"CDSView\"},{\"attributes\":{\"data_source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1131\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1132\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1078\",\"type\":\"CDSView\"}},\"id\":\"1133\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3318\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"2221\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true]},\"id\":\"2542\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1123\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"2539\",\"type\":\"GroupFilter\"},{\"id\":\"2540\",\"type\":\"GroupFilter\"},{\"id\":\"2541\",\"type\":\"GroupFilter\"},{\"id\":\"2542\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"}},\"id\":\"2543\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3699\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3319\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"3651\",\"type\":\"GroupFilter\"},{\"id\":\"3652\",\"type\":\"GroupFilter\"},{\"id\":\"3653\",\"type\":\"GroupFilter\"},{\"id\":\"3654\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"}},\"id\":\"3655\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"1603\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2222\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1124\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3691\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1604\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3318\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3319\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3271\",\"type\":\"CDSView\"}},\"id\":\"3320\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true]},\"id\":\"2223\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"2544\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"3656\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1123\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1124\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1068\",\"type\":\"CDSView\"}},\"id\":\"1125\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3692\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"1602\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"2220\",\"type\":\"GroupFilter\"},{\"id\":\"2221\",\"type\":\"GroupFilter\"},{\"id\":\"2222\",\"type\":\"GroupFilter\"},{\"id\":\"2223\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"}},\"id\":\"2224\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"2545\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"3642\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"3657\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3691\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3692\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3640\",\"type\":\"CDSView\"}},\"id\":\"3693\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1132\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true]},\"id\":\"1605\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3322\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"2225\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2546\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"3617\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3699\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3700\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3650\",\"type\":\"CDSView\"}},\"id\":\"3701\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1127\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"1602\",\"type\":\"GroupFilter\"},{\"id\":\"1603\",\"type\":\"GroupFilter\"},{\"id\":\"1604\",\"type\":\"GroupFilter\"},{\"id\":\"1605\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"}},\"id\":\"1606\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3323\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true]},\"id\":\"2547\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"3621\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"3659\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1128\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"2226\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"4016\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1008\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3322\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3323\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3276\",\"type\":\"CDSView\"}},\"id\":\"3324\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"1607\",\"type\":\"GroupFilter\"},{\"id\":\"1608\",\"type\":\"GroupFilter\"},{\"id\":\"1609\",\"type\":\"GroupFilter\"},{\"id\":\"1610\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"}},\"id\":\"1611\",\"type\":\"CDSView\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"red\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\"],\"origin\":[\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\"],\"p_delay\":[\"None\",\"None\",\"None\",\"None\",1,1,1],\"p_sequence_length\":[1,2,3,4,1,2,3],\"runs\":[1,1,1,1,1,1,1],\"size\":[12.0,12.0,12.0,12.0,12.0,12.0,12.0],\"type\":[\"Final Incumbent\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\"],\"x\":{\"__ndarray__\":\"9XycTryI4z8V1Y/pH4nVP33uZXS0Jq8/nYRVUx7zyL/jng7jxhThP6T+EOPF7tA/ZyIjRMDzOT8=\",\"dtype\":\"float64\",\"shape\":[7]},\"y\":{\"__ndarray__\":\"mzBNdScfwr/cguHH3HPRv8eNZF3Badu/c7FyYAoG47/ygmwPQ8SivzX5O1I4IcS/mkKm6HCl078=\",\"dtype\":\"float64\",\"shape\":[7]},\"zorder\":[\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\"]},\"selected\":{\"id\":\"2630\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"2629\",\"type\":\"UnionRenderers\"}},\"id\":\"1006\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"filters\":[{\"id\":\"2544\",\"type\":\"GroupFilter\"},{\"id\":\"2545\",\"type\":\"GroupFilter\"},{\"id\":\"2546\",\"type\":\"GroupFilter\"},{\"id\":\"2547\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"}},\"id\":\"2548\",\"type\":\"CDSView\"},{\"attributes\":{\"data_source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1127\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1128\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1073\",\"type\":\"CDSView\"}},\"id\":\"1129\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3703\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"3656\",\"type\":\"GroupFilter\"},{\"id\":\"3657\",\"type\":\"GroupFilter\"},{\"id\":\"3658\",\"type\":\"GroupFilter\"},{\"id\":\"3659\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"}},\"id\":\"3660\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true,true]},\"id\":\"1610\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2227\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"2549\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"3661\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1131\",\"type\":\"Scatter\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"red\",\"white\",\"white\",\"white\",\"white\",\"white\"],\"origin\":[\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\"],\"p_delay\":[\"None\",\"None\",\"None\",\"None\",1,1],\"p_sequence_length\":[1,2,3,4,1,2],\"runs\":[1,1,1,1,1,1],\"size\":[12.0,12.0,12.0,12.0,12.0,12.0],\"type\":[\"Final Incumbent\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\"],\"x\":{\"__ndarray__\":\"9XycTryI4z8V1Y/pH4nVP33uZXS0Jq8/nYRVUx7zyL/jng7jxhThP6T+EOPF7tA/\",\"dtype\":\"float64\",\"shape\":[6]},\"y\":{\"__ndarray__\":\"mzBNdScfwr/cguHH3HPRv8eNZF3Badu/c7FyYAoG47/ygmwPQ8SivzX5O1I4IcS/\",\"dtype\":\"float64\",\"shape\":[6]},\"zorder\":[\"0\",\"0\",\"0\",\"0\",\"0\",\"0\"]},\"selected\":{\"id\":\"2299\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"2298\",\"type\":\"UnionRenderers\"}},\"id\":\"1005\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3704\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1609\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true]},\"id\":\"2228\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3658\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3703\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3704\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3655\",\"type\":\"CDSView\"}},\"id\":\"3705\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1135\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"2225\",\"type\":\"GroupFilter\"},{\"id\":\"2226\",\"type\":\"GroupFilter\"},{\"id\":\"2227\",\"type\":\"GroupFilter\"},{\"id\":\"2228\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"}},\"id\":\"2229\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"1608\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"2550\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"3662\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1136\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2263\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2551\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2231\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"1607\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3663\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"4015\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1135\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1136\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1083\",\"type\":\"CDSView\"}},\"id\":\"1137\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3707\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1863\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"1612\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true]},\"id\":\"2552\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"3664\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2232\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"2549\",\"type\":\"GroupFilter\"},{\"id\":\"2550\",\"type\":\"GroupFilter\"},{\"id\":\"2551\",\"type\":\"GroupFilter\"},{\"id\":\"2552\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"}},\"id\":\"2553\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3708\",\"type\":\"Scatter\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"red\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\"],\"origin\":[\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\"],\"p_delay\":[\"None\",\"None\",\"None\",\"None\",1,1,1,1,2,2],\"p_sequence_length\":[1,2,3,4,1,2,3,4,1,2],\"runs\":[1,1,1,1,1,1,1,1,1,1],\"size\":[12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0],\"type\":[\"Final Incumbent\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\"],\"x\":{\"__ndarray__\":\"9XycTryI4z8V1Y/pH4nVP33uZXS0Jq8/nYRVUx7zyL/jng7jxhThP6T+EOPF7tA/ZyIjRMDzOT9NoCikMQ/Pv52J5DpVYt4/vIle97OdyT8=\",\"dtype\":\"float64\",\"shape\":[10]},\"y\":{\"__ndarray__\":\"mzBNdScfwr/cguHH3HPRv8eNZF3Badu/c7FyYAoG47/ygmwPQ8SivzX5O1I4IcS/mkKm6HCl078HiqO8Tmrev+mQWWh3ybc/XU2yO8n9oL8=\",\"dtype\":\"float64\",\"shape\":[10]},\"zorder\":[\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\"]},\"selected\":{\"id\":\"3352\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"3351\",\"type\":\"UnionRenderers\"}},\"id\":\"1008\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"filters\":[{\"id\":\"3661\",\"type\":\"GroupFilter\"},{\"id\":\"3662\",\"type\":\"GroupFilter\"},{\"id\":\"3663\",\"type\":\"GroupFilter\"},{\"id\":\"3664\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"}},\"id\":\"3665\",\"type\":\"CDSView\"},{\"attributes\":{\"data_source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2231\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2232\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2174\",\"type\":\"CDSView\"}},\"id\":\"2233\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3707\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3708\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3660\",\"type\":\"CDSView\"}},\"id\":\"3709\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1139\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3667\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1614\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"2554\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1140\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true]},\"id\":\"1615\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"4017\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"2504\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"2555\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1883\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4018\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1139\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1140\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1088\",\"type\":\"CDSView\"}},\"id\":\"1141\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2235\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3668\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3711\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"1613\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2556\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"3607\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3667\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3668\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3610\",\"type\":\"CDSView\"}},\"id\":\"3669\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2236\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3712\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true]},\"id\":\"2557\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2235\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2236\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2179\",\"type\":\"CDSView\"}},\"id\":\"2237\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3711\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3712\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3665\",\"type\":\"CDSView\"}},\"id\":\"3713\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1143\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"1612\",\"type\":\"GroupFilter\"},{\"id\":\"1613\",\"type\":\"GroupFilter\"},{\"id\":\"1614\",\"type\":\"GroupFilter\"},{\"id\":\"1615\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"}},\"id\":\"1616\",\"type\":\"CDSView\"},{\"attributes\":{\"filters\":[{\"id\":\"2554\",\"type\":\"GroupFilter\"},{\"id\":\"2555\",\"type\":\"GroupFilter\"},{\"id\":\"2556\",\"type\":\"GroupFilter\"},{\"id\":\"2557\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"}},\"id\":\"2558\",\"type\":\"CDSView\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"red\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\",\"white\"],\"origin\":[\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\",\"Random\"],\"p_delay\":[\"None\",\"None\",\"None\",\"None\",1,1,1,1],\"p_sequence_length\":[1,2,3,4,1,2,3,4],\"runs\":[1,1,1,1,1,1,1,1],\"size\":[12.0,12.0,12.0,12.0,12.0,12.0,12.0,12.0],\"type\":[\"Final Incumbent\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\"],\"x\":{\"__ndarray__\":\"9XycTryI4z8V1Y/pH4nVP33uZXS0Jq8/nYRVUx7zyL/jng7jxhThP6T+EOPF7tA/ZyIjRMDzOT9NoCikMQ/Pvw==\",\"dtype\":\"float64\",\"shape\":[8]},\"y\":{\"__ndarray__\":\"mzBNdScfwr/cguHH3HPRv8eNZF3Badu/c7FyYAoG47/ygmwPQ8SivzX5O1I4IcS/mkKm6HCl078HiqO8Tmrevw==\",\"dtype\":\"float64\",\"shape\":[8]},\"zorder\":[\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\",\"0\"]},\"selected\":{\"id\":\"2981\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"2980\",\"type\":\"UnionRenderers\"}},\"id\":\"1007\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"data_source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2259\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2260\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2209\",\"type\":\"CDSView\"}},\"id\":\"2261\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1144\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3671\",\"type\":\"Scatter\"},{\"attributes\":{\"callback\":null,\"renderers\":[{\"id\":\"1117\",\"type\":\"GlyphRenderer\"},{\"id\":\"1121\",\"type\":\"GlyphRenderer\"},{\"id\":\"1125\",\"type\":\"GlyphRenderer\"},{\"id\":\"1129\",\"type\":\"GlyphRenderer\"},{\"id\":\"1133\",\"type\":\"GlyphRenderer\"},{\"id\":\"1137\",\"type\":\"GlyphRenderer\"},{\"id\":\"1141\",\"type\":\"GlyphRenderer\"},{\"id\":\"1145\",\"type\":\"GlyphRenderer\"},{\"id\":\"1149\",\"type\":\"GlyphRenderer\"},{\"id\":\"1153\",\"type\":\"GlyphRenderer\"},{\"id\":\"1157\",\"type\":\"GlyphRenderer\"},{\"id\":\"1161\",\"type\":\"GlyphRenderer\"},{\"id\":\"1366\",\"type\":\"GlyphRenderer\"},{\"id\":\"1370\",\"type\":\"GlyphRenderer\"},{\"id\":\"1374\",\"type\":\"GlyphRenderer\"},{\"id\":\"1378\",\"type\":\"GlyphRenderer\"},{\"id\":\"1382\",\"type\":\"GlyphRenderer\"},{\"id\":\"1386\",\"type\":\"GlyphRenderer\"},{\"id\":\"1390\",\"type\":\"GlyphRenderer\"},{\"id\":\"1394\",\"type\":\"GlyphRenderer\"},{\"id\":\"1398\",\"type\":\"GlyphRenderer\"},{\"id\":\"1402\",\"type\":\"GlyphRenderer\"},{\"id\":\"1406\",\"type\":\"GlyphRenderer\"},{\"id\":\"1410\",\"type\":\"GlyphRenderer\"},{\"id\":\"1635\",\"type\":\"GlyphRenderer\"},{\"id\":\"1639\",\"type\":\"GlyphRenderer\"},{\"id\":\"1643\",\"type\":\"GlyphRenderer\"},{\"id\":\"1647\",\"type\":\"GlyphRenderer\"},{\"id\":\"1651\",\"type\":\"GlyphRenderer\"},{\"id\":\"1655\",\"type\":\"GlyphRenderer\"},{\"id\":\"1659\",\"type\":\"GlyphRenderer\"},{\"id\":\"1663\",\"type\":\"GlyphRenderer\"},{\"id\":\"1667\",\"type\":\"GlyphRenderer\"},{\"id\":\"1671\",\"type\":\"GlyphRenderer\"},{\"id\":\"1675\",\"type\":\"GlyphRenderer\"},{\"id\":\"1679\",\"type\":\"GlyphRenderer\"},{\"id\":\"1924\",\"type\":\"GlyphRenderer\"},{\"id\":\"1928\",\"type\":\"GlyphRenderer\"},{\"id\":\"1932\",\"type\":\"GlyphRenderer\"},{\"id\":\"1936\",\"type\":\"GlyphRenderer\"},{\"id\":\"1940\",\"type\":\"GlyphRenderer\"},{\"id\":\"1944\",\"type\":\"GlyphRenderer\"},{\"id\":\"1948\",\"type\":\"GlyphRenderer\"},{\"id\":\"1952\",\"type\":\"GlyphRenderer\"},{\"id\":\"1956\",\"type\":\"GlyphRenderer\"},{\"id\":\"1960\",\"type\":\"GlyphRenderer\"},{\"id\":\"1964\",\"type\":\"GlyphRenderer\"},{\"id\":\"1968\",\"type\":\"GlyphRenderer\"},{\"id\":\"2233\",\"type\":\"GlyphRenderer\"},{\"id\":\"2237\",\"type\":\"GlyphRenderer\"},{\"id\":\"2241\",\"type\":\"GlyphRenderer\"},{\"id\":\"2245\",\"type\":\"GlyphRenderer\"},{\"id\":\"2249\",\"type\":\"GlyphRenderer\"},{\"id\":\"2253\",\"type\":\"GlyphRenderer\"},{\"id\":\"2257\",\"type\":\"GlyphRenderer\"},{\"id\":\"2261\",\"type\":\"GlyphRenderer\"},{\"id\":\"2265\",\"type\":\"GlyphRenderer\"},{\"id\":\"2269\",\"type\":\"GlyphRenderer\"},{\"id\":\"2273\",\"type\":\"GlyphRenderer\"},{\"id\":\"2277\",\"type\":\"GlyphRenderer\"},{\"id\":\"2562\",\"type\":\"GlyphRenderer\"},{\"id\":\"2566\",\"type\":\"GlyphRenderer\"},{\"id\":\"2570\",\"type\":\"GlyphRenderer\"},{\"id\":\"2574\",\"type\":\"GlyphRenderer\"},{\"id\":\"2578\",\"type\":\"GlyphRenderer\"},{\"id\":\"2582\",\"type\":\"GlyphRenderer\"},{\"id\":\"2586\",\"type\":\"GlyphRenderer\"},{\"id\":\"2590\",\"type\":\"GlyphRenderer\"},{\"id\":\"2594\",\"type\":\"GlyphRenderer\"},{\"id\":\"2598\",\"type\":\"GlyphRenderer\"},{\"id\":\"2602\",\"type\":\"GlyphRenderer\"},{\"id\":\"2606\",\"type\":\"GlyphRenderer\"},{\"id\":\"2911\",\"type\":\"GlyphRenderer\"},{\"id\":\"2915\",\"type\":\"GlyphRenderer\"},{\"id\":\"2919\",\"type\":\"GlyphRenderer\"},{\"id\":\"2923\",\"type\":\"GlyphRenderer\"},{\"id\":\"2927\",\"type\":\"GlyphRenderer\"},{\"id\":\"2931\",\"type\":\"GlyphRenderer\"},{\"id\":\"2935\",\"type\":\"GlyphRenderer\"},{\"id\":\"2939\",\"type\":\"GlyphRenderer\"},{\"id\":\"2943\",\"type\":\"GlyphRenderer\"},{\"id\":\"2947\",\"type\":\"GlyphRenderer\"},{\"id\":\"2951\",\"type\":\"GlyphRenderer\"},{\"id\":\"2955\",\"type\":\"GlyphRenderer\"},{\"id\":\"3280\",\"type\":\"GlyphRenderer\"},{\"id\":\"3284\",\"type\":\"GlyphRenderer\"},{\"id\":\"3288\",\"type\":\"GlyphRenderer\"},{\"id\":\"3292\",\"type\":\"GlyphRenderer\"},{\"id\":\"3296\",\"type\":\"GlyphRenderer\"},{\"id\":\"3300\",\"type\":\"GlyphRenderer\"},{\"id\":\"3304\",\"type\":\"GlyphRenderer\"},{\"id\":\"3308\",\"type\":\"GlyphRenderer\"},{\"id\":\"3312\",\"type\":\"GlyphRenderer\"},{\"id\":\"3316\",\"type\":\"GlyphRenderer\"},{\"id\":\"3320\",\"type\":\"GlyphRenderer\"},{\"id\":\"3324\",\"type\":\"GlyphRenderer\"},{\"id\":\"3669\",\"type\":\"GlyphRenderer\"},{\"id\":\"3673\",\"type\":\"GlyphRenderer\"},{\"id\":\"3677\",\"type\":\"GlyphRenderer\"},{\"id\":\"3681\",\"type\":\"GlyphRenderer\"},{\"id\":\"3685\",\"type\":\"GlyphRenderer\"},{\"id\":\"3689\",\"type\":\"GlyphRenderer\"},{\"id\":\"3693\",\"type\":\"GlyphRenderer\"},{\"id\":\"3697\",\"type\":\"GlyphRenderer\"},{\"id\":\"3701\",\"type\":\"GlyphRenderer\"},{\"id\":\"3705\",\"type\":\"GlyphRenderer\"},{\"id\":\"3709\",\"type\":\"GlyphRenderer\"},{\"id\":\"3713\",\"type\":\"GlyphRenderer\"},{\"id\":\"4138\",\"type\":\"GlyphRenderer\"},{\"id\":\"4142\",\"type\":\"GlyphRenderer\"},{\"id\":\"4146\",\"type\":\"GlyphRenderer\"},{\"id\":\"4150\",\"type\":\"GlyphRenderer\"},{\"id\":\"4154\",\"type\":\"GlyphRenderer\"},{\"id\":\"4158\",\"type\":\"GlyphRenderer\"},{\"id\":\"4162\",\"type\":\"GlyphRenderer\"},{\"id\":\"4166\",\"type\":\"GlyphRenderer\"},{\"id\":\"4170\",\"type\":\"GlyphRenderer\"},{\"id\":\"4174\",\"type\":\"GlyphRenderer\"},{\"id\":\"4178\",\"type\":\"GlyphRenderer\"},{\"id\":\"4182\",\"type\":\"GlyphRenderer\"},{\"id\":\"4186\",\"type\":\"GlyphRenderer\"},{\"id\":\"4190\",\"type\":\"GlyphRenderer\"},{\"id\":\"4194\",\"type\":\"GlyphRenderer\"},{\"id\":\"4198\",\"type\":\"GlyphRenderer\"},{\"id\":\"4202\",\"type\":\"GlyphRenderer\"},{\"id\":\"4206\",\"type\":\"GlyphRenderer\"},{\"id\":\"4210\",\"type\":\"GlyphRenderer\"},{\"id\":\"4214\",\"type\":\"GlyphRenderer\"},{\"id\":\"4218\",\"type\":\"GlyphRenderer\"},{\"id\":\"4222\",\"type\":\"GlyphRenderer\"},{\"id\":\"4226\",\"type\":\"GlyphRenderer\"},{\"id\":\"4230\",\"type\":\"GlyphRenderer\"}],\"tooltips\":[[\"type\",\"@type\"],[\"origin\",\"@origin\"],[\"runs\",\"@runs\"],[\"delay\",\"@p_delay\"],[\"sequence_length\",\"@p_sequence_length\"]]},\"id\":\"4552\",\"type\":\"HoverTool\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"1617\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1143\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1144\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1093\",\"type\":\"CDSView\"}},\"id\":\"1145\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2239\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2560\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3672\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"1618\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3671\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3672\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3615\",\"type\":\"CDSView\"}},\"id\":\"3673\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2240\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2561\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true]},\"id\":\"1595\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"3614\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2239\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2240\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2184\",\"type\":\"CDSView\"}},\"id\":\"2241\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1147\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2560\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2561\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2503\",\"type\":\"CDSView\"}},\"id\":\"2562\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3695\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3696\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3645\",\"type\":\"CDSView\"}},\"id\":\"3697\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1629\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1148\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2260\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3675\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1594\",\"type\":\"GroupFilter\"},{\"attributes\":{},\"id\":\"3351\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"data_source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1147\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1148\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1098\",\"type\":\"CDSView\"}},\"id\":\"1149\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2243\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2589\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2564\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3676\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"3352\",\"type\":\"Selection\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"3616\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3675\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3676\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3620\",\"type\":\"CDSView\"}},\"id\":\"3677\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2244\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1619\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2565\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"3644\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2243\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2244\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2189\",\"type\":\"CDSView\"}},\"id\":\"2245\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1151\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"3641\",\"type\":\"GroupFilter\"},{\"id\":\"3642\",\"type\":\"GroupFilter\"},{\"id\":\"3643\",\"type\":\"GroupFilter\"},{\"id\":\"3644\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"}},\"id\":\"3645\",\"type\":\"CDSView\"},{\"attributes\":{\"data_source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2564\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2565\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2508\",\"type\":\"CDSView\"}},\"id\":\"2566\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3696\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true]},\"id\":\"1620\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3219\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1152\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2259\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3679\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true]},\"id\":\"1625\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"3609\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"3647\",\"type\":\"GroupFilter\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"red\",\"white\",\"white\",\"white\",\"white\"],\"origin\":[\"Random\",\"Random\",\"Random\",\"Random\",\"Random\"],\"p_delay\":[\"None\",\"None\",\"None\",\"None\",1],\"p_sequence_length\":[1,2,3,4,1],\"runs\":[1,1,1,1,1],\"size\":[12.0,12.0,12.0,12.0,12.0],\"type\":[\"Final Incumbent\",\"Candidate\",\"Candidate\",\"Candidate\",\"Candidate\"],\"x\":{\"__ndarray__\":\"9XycTryI4z8V1Y/pH4nVP33uZXS0Jq8/nYRVUx7zyL/jng7jxhThPw==\",\"dtype\":\"float64\",\"shape\":[5]},\"y\":{\"__ndarray__\":\"mzBNdScfwr/cguHH3HPRv8eNZF3Badu/c7FyYAoG47/ygmwPQ8Sivw==\",\"dtype\":\"float64\",\"shape\":[5]},\"zorder\":[\"0\",\"0\",\"0\",\"0\",\"0\"]},\"selected\":{\"id\":\"1988\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1987\",\"type\":\"UnionRenderers\"}},\"id\":\"1004\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"data_source\":{\"id\":\"1001\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"1151\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"1152\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"1103\",\"type\":\"CDSView\"}},\"id\":\"1153\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2247\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"1617\",\"type\":\"GroupFilter\"},{\"id\":\"1618\",\"type\":\"GroupFilter\"},{\"id\":\"1619\",\"type\":\"GroupFilter\"},{\"id\":\"1620\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1003\",\"type\":\"ColumnDataSource\"}},\"id\":\"1621\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2568\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2588\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3680\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1009\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"3679\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"3680\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"3625\",\"type\":\"CDSView\"}},\"id\":\"3681\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2248\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"1624\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"circle_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2569\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"3217\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"3641\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2247\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2248\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2194\",\"type\":\"CDSView\"}},\"id\":\"2249\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1155\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4201\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2568\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2569\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2513\",\"type\":\"CDSView\"}},\"id\":\"2570\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3695\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"1622\",\"type\":\"GroupFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"3639\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"1156\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"3683\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"1623\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3643\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"3622\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"2878\",\"type\":\"GroupFilter\"},{\"id\":\"2879\",\"type\":\"GroupFilter\"},{\"id\":\"2880\",\"type\":\"GroupFilter\"},{\"id\":\"2881\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"}},\"id\":\"2882\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4184\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"4110\",\"type\":\"GroupFilter\"},{\"id\":\"4111\",\"type\":\"GroupFilter\"},{\"id\":\"4112\",\"type\":\"GroupFilter\"},{\"id\":\"4113\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4114\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2251\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4185\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true]},\"id\":\"2881\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"4115\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"square_x\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2252\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4184\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4185\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4079\",\"type\":\"CDSView\"}},\"id\":\"4186\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"data_source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2251\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2252\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2199\",\"type\":\"CDSView\"}},\"id\":\"2253\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"2884\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"4116\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4204\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4205\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4104\",\"type\":\"CDSView\"}},\"id\":\"4206\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2885\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"4117\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4188\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2501\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"2873\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2255\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"2883\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3623\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4189\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4118\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2256\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"4115\",\"type\":\"GroupFilter\"},{\"id\":\"4116\",\"type\":\"GroupFilter\"},{\"id\":\"4117\",\"type\":\"GroupFilter\"},{\"id\":\"4118\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4119\",\"type\":\"CDSView\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4188\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4189\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4084\",\"type\":\"CDSView\"}},\"id\":\"4190\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true]},\"id\":\"2886\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2255\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2256\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2204\",\"type\":\"CDSView\"}},\"id\":\"2257\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2880\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"4120\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2267\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"2879\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4205\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"4121\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2268\",\"type\":\"Scatter\"},{\"attributes\":{\"active\":[0],\"callback\":{\"id\":\"4556\",\"type\":\"CustomJS\"},\"labels\":[\"dqn seq del\"]},\"id\":\"4555\",\"type\":\"CheckboxButtonGroup\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"20\"},\"id\":\"4122\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2267\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2268\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2219\",\"type\":\"CDSView\"}},\"id\":\"2269\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"2883\",\"type\":\"GroupFilter\"},{\"id\":\"2884\",\"type\":\"GroupFilter\"},{\"id\":\"2885\",\"type\":\"GroupFilter\"},{\"id\":\"2886\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"}},\"id\":\"2887\",\"type\":\"CDSView\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"3624\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4208\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4123\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true]},\"id\":\"2502\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2909\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4209\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"4120\",\"type\":\"GroupFilter\"},{\"id\":\"4121\",\"type\":\"GroupFilter\"},{\"id\":\"4122\",\"type\":\"GroupFilter\"},{\"id\":\"4123\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4124\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2271\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4208\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4209\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4109\",\"type\":\"CDSView\"}},\"id\":\"4210\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"4125\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2272\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2910\",\"type\":\"Scatter\"},{\"attributes\":{\"text\":\"Showing only configurations evaluated in:\"},\"id\":\"4557\",\"type\":\"Div\"},{\"attributes\":{\"data_source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2271\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2272\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2224\",\"type\":\"CDSView\"}},\"id\":\"2273\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"4126\",\"type\":\"GroupFilter\"},{\"attributes\":{\"args\":{\"checkbox\":{\"id\":\"4555\",\"type\":\"CheckboxButtonGroup\"},\"glyph0\":{\"id\":\"1117\",\"type\":\"GlyphRenderer\"},\"glyph1\":{\"id\":\"1121\",\"type\":\"GlyphRenderer\"},\"glyph10\":{\"id\":\"1157\",\"type\":\"GlyphRenderer\"},\"glyph100\":{\"id\":\"3685\",\"type\":\"GlyphRenderer\"},\"glyph101\":{\"id\":\"3689\",\"type\":\"GlyphRenderer\"},\"glyph102\":{\"id\":\"3693\",\"type\":\"GlyphRenderer\"},\"glyph103\":{\"id\":\"3697\",\"type\":\"GlyphRenderer\"},\"glyph104\":{\"id\":\"3701\",\"type\":\"GlyphRenderer\"},\"glyph105\":{\"id\":\"3705\",\"type\":\"GlyphRenderer\"},\"glyph106\":{\"id\":\"3709\",\"type\":\"GlyphRenderer\"},\"glyph107\":{\"id\":\"3713\",\"type\":\"GlyphRenderer\"},\"glyph108\":{\"id\":\"4138\",\"type\":\"GlyphRenderer\"},\"glyph109\":{\"id\":\"4142\",\"type\":\"GlyphRenderer\"},\"glyph11\":{\"id\":\"1161\",\"type\":\"GlyphRenderer\"},\"glyph110\":{\"id\":\"4146\",\"type\":\"GlyphRenderer\"},\"glyph111\":{\"id\":\"4150\",\"type\":\"GlyphRenderer\"},\"glyph112\":{\"id\":\"4154\",\"type\":\"GlyphRenderer\"},\"glyph113\":{\"id\":\"4158\",\"type\":\"GlyphRenderer\"},\"glyph114\":{\"id\":\"4162\",\"type\":\"GlyphRenderer\"},\"glyph115\":{\"id\":\"4166\",\"type\":\"GlyphRenderer\"},\"glyph116\":{\"id\":\"4170\",\"type\":\"GlyphRenderer\"},\"glyph117\":{\"id\":\"4174\",\"type\":\"GlyphRenderer\"},\"glyph118\":{\"id\":\"4178\",\"type\":\"GlyphRenderer\"},\"glyph119\":{\"id\":\"4182\",\"type\":\"GlyphRenderer\"},\"glyph12\":{\"id\":\"1366\",\"type\":\"GlyphRenderer\"},\"glyph120\":{\"id\":\"4186\",\"type\":\"GlyphRenderer\"},\"glyph121\":{\"id\":\"4190\",\"type\":\"GlyphRenderer\"},\"glyph122\":{\"id\":\"4194\",\"type\":\"GlyphRenderer\"},\"glyph123\":{\"id\":\"4198\",\"type\":\"GlyphRenderer\"},\"glyph124\":{\"id\":\"4202\",\"type\":\"GlyphRenderer\"},\"glyph125\":{\"id\":\"4206\",\"type\":\"GlyphRenderer\"},\"glyph126\":{\"id\":\"4210\",\"type\":\"GlyphRenderer\"},\"glyph127\":{\"id\":\"4214\",\"type\":\"GlyphRenderer\"},\"glyph128\":{\"id\":\"4218\",\"type\":\"GlyphRenderer\"},\"glyph129\":{\"id\":\"4222\",\"type\":\"GlyphRenderer\"},\"glyph13\":{\"id\":\"1370\",\"type\":\"GlyphRenderer\"},\"glyph130\":{\"id\":\"4226\",\"type\":\"GlyphRenderer\"},\"glyph131\":{\"id\":\"4230\",\"type\":\"GlyphRenderer\"},\"glyph14\":{\"id\":\"1374\",\"type\":\"GlyphRenderer\"},\"glyph15\":{\"id\":\"1378\",\"type\":\"GlyphRenderer\"},\"glyph16\":{\"id\":\"1382\",\"type\":\"GlyphRenderer\"},\"glyph17\":{\"id\":\"1386\",\"type\":\"GlyphRenderer\"},\"glyph18\":{\"id\":\"1390\",\"type\":\"GlyphRenderer\"},\"glyph19\":{\"id\":\"1394\",\"type\":\"GlyphRenderer\"},\"glyph2\":{\"id\":\"1125\",\"type\":\"GlyphRenderer\"},\"glyph20\":{\"id\":\"1398\",\"type\":\"GlyphRenderer\"},\"glyph21\":{\"id\":\"1402\",\"type\":\"GlyphRenderer\"},\"glyph22\":{\"id\":\"1406\",\"type\":\"GlyphRenderer\"},\"glyph23\":{\"id\":\"1410\",\"type\":\"GlyphRenderer\"},\"glyph24\":{\"id\":\"1635\",\"type\":\"GlyphRenderer\"},\"glyph25\":{\"id\":\"1639\",\"type\":\"GlyphRenderer\"},\"glyph26\":{\"id\":\"1643\",\"type\":\"GlyphRenderer\"},\"glyph27\":{\"id\":\"1647\",\"type\":\"GlyphRenderer\"},\"glyph28\":{\"id\":\"1651\",\"type\":\"GlyphRenderer\"},\"glyph29\":{\"id\":\"1655\",\"type\":\"GlyphRenderer\"},\"glyph3\":{\"id\":\"1129\",\"type\":\"GlyphRenderer\"},\"glyph30\":{\"id\":\"1659\",\"type\":\"GlyphRenderer\"},\"glyph31\":{\"id\":\"1663\",\"type\":\"GlyphRenderer\"},\"glyph32\":{\"id\":\"1667\",\"type\":\"GlyphRenderer\"},\"glyph33\":{\"id\":\"1671\",\"type\":\"GlyphRenderer\"},\"glyph34\":{\"id\":\"1675\",\"type\":\"GlyphRenderer\"},\"glyph35\":{\"id\":\"1679\",\"type\":\"GlyphRenderer\"},\"glyph36\":{\"id\":\"1924\",\"type\":\"GlyphRenderer\"},\"glyph37\":{\"id\":\"1928\",\"type\":\"GlyphRenderer\"},\"glyph38\":{\"id\":\"1932\",\"type\":\"GlyphRenderer\"},\"glyph39\":{\"id\":\"1936\",\"type\":\"GlyphRenderer\"},\"glyph4\":{\"id\":\"1133\",\"type\":\"GlyphRenderer\"},\"glyph40\":{\"id\":\"1940\",\"type\":\"GlyphRenderer\"},\"glyph41\":{\"id\":\"1944\",\"type\":\"GlyphRenderer\"},\"glyph42\":{\"id\":\"1948\",\"type\":\"GlyphRenderer\"},\"glyph43\":{\"id\":\"1952\",\"type\":\"GlyphRenderer\"},\"glyph44\":{\"id\":\"1956\",\"type\":\"GlyphRenderer\"},\"glyph45\":{\"id\":\"1960\",\"type\":\"GlyphRenderer\"},\"glyph46\":{\"id\":\"1964\",\"type\":\"GlyphRenderer\"},\"glyph47\":{\"id\":\"1968\",\"type\":\"GlyphRenderer\"},\"glyph48\":{\"id\":\"2233\",\"type\":\"GlyphRenderer\"},\"glyph49\":{\"id\":\"2237\",\"type\":\"GlyphRenderer\"},\"glyph5\":{\"id\":\"1137\",\"type\":\"GlyphRenderer\"},\"glyph50\":{\"id\":\"2241\",\"type\":\"GlyphRenderer\"},\"glyph51\":{\"id\":\"2245\",\"type\":\"GlyphRenderer\"},\"glyph52\":{\"id\":\"2249\",\"type\":\"GlyphRenderer\"},\"glyph53\":{\"id\":\"2253\",\"type\":\"GlyphRenderer\"},\"glyph54\":{\"id\":\"2257\",\"type\":\"GlyphRenderer\"},\"glyph55\":{\"id\":\"2261\",\"type\":\"GlyphRenderer\"},\"glyph56\":{\"id\":\"2265\",\"type\":\"GlyphRenderer\"},\"glyph57\":{\"id\":\"2269\",\"type\":\"GlyphRenderer\"},\"glyph58\":{\"id\":\"2273\",\"type\":\"GlyphRenderer\"},\"glyph59\":{\"id\":\"2277\",\"type\":\"GlyphRenderer\"},\"glyph6\":{\"id\":\"1141\",\"type\":\"GlyphRenderer\"},\"glyph60\":{\"id\":\"2562\",\"type\":\"GlyphRenderer\"},\"glyph61\":{\"id\":\"2566\",\"type\":\"GlyphRenderer\"},\"glyph62\":{\"id\":\"2570\",\"type\":\"GlyphRenderer\"},\"glyph63\":{\"id\":\"2574\",\"type\":\"GlyphRenderer\"},\"glyph64\":{\"id\":\"2578\",\"type\":\"GlyphRenderer\"},\"glyph65\":{\"id\":\"2582\",\"type\":\"GlyphRenderer\"},\"glyph66\":{\"id\":\"2586\",\"type\":\"GlyphRenderer\"},\"glyph67\":{\"id\":\"2590\",\"type\":\"GlyphRenderer\"},\"glyph68\":{\"id\":\"2594\",\"type\":\"GlyphRenderer\"},\"glyph69\":{\"id\":\"2598\",\"type\":\"GlyphRenderer\"},\"glyph7\":{\"id\":\"1145\",\"type\":\"GlyphRenderer\"},\"glyph70\":{\"id\":\"2602\",\"type\":\"GlyphRenderer\"},\"glyph71\":{\"id\":\"2606\",\"type\":\"GlyphRenderer\"},\"glyph72\":{\"id\":\"2911\",\"type\":\"GlyphRenderer\"},\"glyph73\":{\"id\":\"2915\",\"type\":\"GlyphRenderer\"},\"glyph74\":{\"id\":\"2919\",\"type\":\"GlyphRenderer\"},\"glyph75\":{\"id\":\"2923\",\"type\":\"GlyphRenderer\"},\"glyph76\":{\"id\":\"2927\",\"type\":\"GlyphRenderer\"},\"glyph77\":{\"id\":\"2931\",\"type\":\"GlyphRenderer\"},\"glyph78\":{\"id\":\"2935\",\"type\":\"GlyphRenderer\"},\"glyph79\":{\"id\":\"2939\",\"type\":\"GlyphRenderer\"},\"glyph8\":{\"id\":\"1149\",\"type\":\"GlyphRenderer\"},\"glyph80\":{\"id\":\"2943\",\"type\":\"GlyphRenderer\"},\"glyph81\":{\"id\":\"2947\",\"type\":\"GlyphRenderer\"},\"glyph82\":{\"id\":\"2951\",\"type\":\"GlyphRenderer\"},\"glyph83\":{\"id\":\"2955\",\"type\":\"GlyphRenderer\"},\"glyph84\":{\"id\":\"3280\",\"type\":\"GlyphRenderer\"},\"glyph85\":{\"id\":\"3284\",\"type\":\"GlyphRenderer\"},\"glyph86\":{\"id\":\"3288\",\"type\":\"GlyphRenderer\"},\"glyph87\":{\"id\":\"3292\",\"type\":\"GlyphRenderer\"},\"glyph88\":{\"id\":\"3296\",\"type\":\"GlyphRenderer\"},\"glyph89\":{\"id\":\"3300\",\"type\":\"GlyphRenderer\"},\"glyph9\":{\"id\":\"1153\",\"type\":\"GlyphRenderer\"},\"glyph90\":{\"id\":\"3304\",\"type\":\"GlyphRenderer\"},\"glyph91\":{\"id\":\"3308\",\"type\":\"GlyphRenderer\"},\"glyph92\":{\"id\":\"3312\",\"type\":\"GlyphRenderer\"},\"glyph93\":{\"id\":\"3316\",\"type\":\"GlyphRenderer\"},\"glyph94\":{\"id\":\"3320\",\"type\":\"GlyphRenderer\"},\"glyph95\":{\"id\":\"3324\",\"type\":\"GlyphRenderer\"},\"glyph96\":{\"id\":\"3669\",\"type\":\"GlyphRenderer\"},\"glyph97\":{\"id\":\"3673\",\"type\":\"GlyphRenderer\"},\"glyph98\":{\"id\":\"3677\",\"type\":\"GlyphRenderer\"},\"glyph99\":{\"id\":\"3681\",\"type\":\"GlyphRenderer\"},\"time_slider\":{\"id\":\"4554\",\"type\":\"Slider\"}},\"code\":\"checkbox.active = [];var glyphs = [glyph0, glyph1, glyph2, glyph3, glyph4, glyph5, glyph6, glyph7, glyph8, glyph9, glyph10, glyph11, glyph12, glyph13, glyph14, glyph15, glyph16, glyph17, glyph18, glyph19, glyph20, glyph21, glyph22, glyph23, glyph24, glyph25, glyph26, glyph27, glyph28, glyph29, glyph30, glyph31, glyph32, glyph33, glyph34, glyph35, glyph36, glyph37, glyph38, glyph39, glyph40, glyph41, glyph42, glyph43, glyph44, glyph45, glyph46, glyph47, glyph48, glyph49, glyph50, glyph51, glyph52, glyph53, glyph54, glyph55, glyph56, glyph57, glyph58, glyph59, glyph60, glyph61, glyph62, glyph63, glyph64, glyph65, glyph66, glyph67, glyph68, glyph69, glyph70, glyph71, glyph72, glyph73, glyph74, glyph75, glyph76, glyph77, glyph78, glyph79, glyph80, glyph81, glyph82, glyph83, glyph84, glyph85, glyph86, glyph87, glyph88, glyph89, glyph90, glyph91, glyph92, glyph93, glyph94, glyph95, glyph96, glyph97, glyph98, glyph99, glyph100, glyph101, glyph102, glyph103, glyph104, glyph105, glyph106, glyph107, glyph108, glyph109, glyph110, glyph111, glyph112, glyph113, glyph114, glyph115, glyph116, glyph117, glyph118, glyph119, glyph120, glyph121, glyph122, glyph123, glyph124, glyph125, glyph126, glyph127, glyph128, glyph129, glyph130, glyph131];var overtime = [[0,1,2,3,4,5,6,7,8,9,10,11],[12,13,14,15,16,17,18,19,20,21,22,23],[24,25,26,27,28,29,30,31,32,33,34,35],[36,37,38,39,40,41,42,43,44,45,46,47],[48,49,50,51,52,53,54,55,56,57,58,59],[60,61,62,63,64,65,66,67,68,69,70,71],[72,73,74,75,76,77,78,79,80,81,82,83],[84,85,86,87,88,89,90,91,92,93,94,95],[96,97,98,99,100,101,102,103,104,105,106,107],[108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131]];var runs = [[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131]];\\n glyphs.forEach(function(g) {\\n g.visible = false;\\n })\\n // union function\\n function union_arrays(x, y) {\\n var obj = {};\\n for (var i = x.length-1; i >= 0; -- i)\\n obj[x[i]] = x[i];\\n for (var i = y.length-1; i >= 0; -- i)\\n obj[y[i]] = y[i];\\n var res = []\\n for (var k in obj) {\\n if (obj.hasOwnProperty(k)) // <-- optional\\n res.push(obj[k]);\\n }\\n return res;\\n }\\n console.log(\\\"Timeslider: \\\" + time_slider.value);\\n console.log(\\\"Checkbox: \\\" + checkbox.active);var slider_labels = ['2.10', '3.20', '4.30', '5.40', '6.50', '7.60', '8.70', '10.90', '15.30', '21.90'];console.log(\\\"Detected slider_labels: \\\" + slider_labels);time_slider.title = \\\"Until wallclocktime \\\" + slider_labels[time_slider.value - 1] + \\\". Step no.\\\"; \\n var activate = [];\\n // if we want multiple checkboxes at the same time, we need to combine the arrays\\n checkbox.active.forEach(function(c) {\\n activate = union_arrays(activate, runs[c]);\\n })\\n // now the intersection of timeslider-activated and checkbox-activated\\n activate = activate.filter(value => -1 !== overtime[time_slider.value - 1].indexOf(value));\\n activate.forEach(function(idx) {\\n glyphs[idx].visible = true;\\n })\\n \"},\"id\":\"4560\",\"type\":\"CustomJS\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4212\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Candidate\"},\"id\":\"2499\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2890\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"4127\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4213\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"2500\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Unknown\"},\"id\":\"2894\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2275\",\"type\":\"Scatter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true]},\"id\":\"2891\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4128\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4212\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4213\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4114\",\"type\":\"CDSView\"}},\"id\":\"4214\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"2889\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"2276\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"4125\",\"type\":\"GroupFilter\"},{\"id\":\"4126\",\"type\":\"GroupFilter\"},{\"id\":\"4127\",\"type\":\"GroupFilter\"},{\"id\":\"4128\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4129\",\"type\":\"CDSView\"},{\"attributes\":{\"data_source\":{\"id\":\"1005\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"2275\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"2276\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"2229\",\"type\":\"CDSView\"}},\"id\":\"2277\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"callback\":{\"id\":\"4560\",\"type\":\"CustomJS\"},\"icon\":null,\"label\":\"None\"},\"id\":\"4561\",\"type\":\"Button\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"4130\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4216\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Final Incumbent\"},\"id\":\"2888\",\"type\":\"GroupFilter\"},{\"attributes\":{\"filters\":[{\"id\":\"2888\",\"type\":\"GroupFilter\"},{\"id\":\"2889\",\"type\":\"GroupFilter\"},{\"id\":\"2890\",\"type\":\"GroupFilter\"},{\"id\":\"2891\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"}},\"id\":\"2892\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4217\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"4131\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Incumbent\"},\"id\":\"3626\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4216\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4217\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4119\",\"type\":\"CDSView\"}},\"id\":\"4218\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"2893\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"20\"},\"id\":\"4132\",\"type\":\"GroupFilter\"},{\"attributes\":{\"args\":{\"checkbox\":{\"id\":\"4555\",\"type\":\"CheckboxButtonGroup\"},\"glyph0\":{\"id\":\"1117\",\"type\":\"GlyphRenderer\"},\"glyph1\":{\"id\":\"1121\",\"type\":\"GlyphRenderer\"},\"glyph10\":{\"id\":\"1157\",\"type\":\"GlyphRenderer\"},\"glyph100\":{\"id\":\"3685\",\"type\":\"GlyphRenderer\"},\"glyph101\":{\"id\":\"3689\",\"type\":\"GlyphRenderer\"},\"glyph102\":{\"id\":\"3693\",\"type\":\"GlyphRenderer\"},\"glyph103\":{\"id\":\"3697\",\"type\":\"GlyphRenderer\"},\"glyph104\":{\"id\":\"3701\",\"type\":\"GlyphRenderer\"},\"glyph105\":{\"id\":\"3705\",\"type\":\"GlyphRenderer\"},\"glyph106\":{\"id\":\"3709\",\"type\":\"GlyphRenderer\"},\"glyph107\":{\"id\":\"3713\",\"type\":\"GlyphRenderer\"},\"glyph108\":{\"id\":\"4138\",\"type\":\"GlyphRenderer\"},\"glyph109\":{\"id\":\"4142\",\"type\":\"GlyphRenderer\"},\"glyph11\":{\"id\":\"1161\",\"type\":\"GlyphRenderer\"},\"glyph110\":{\"id\":\"4146\",\"type\":\"GlyphRenderer\"},\"glyph111\":{\"id\":\"4150\",\"type\":\"GlyphRenderer\"},\"glyph112\":{\"id\":\"4154\",\"type\":\"GlyphRenderer\"},\"glyph113\":{\"id\":\"4158\",\"type\":\"GlyphRenderer\"},\"glyph114\":{\"id\":\"4162\",\"type\":\"GlyphRenderer\"},\"glyph115\":{\"id\":\"4166\",\"type\":\"GlyphRenderer\"},\"glyph116\":{\"id\":\"4170\",\"type\":\"GlyphRenderer\"},\"glyph117\":{\"id\":\"4174\",\"type\":\"GlyphRenderer\"},\"glyph118\":{\"id\":\"4178\",\"type\":\"GlyphRenderer\"},\"glyph119\":{\"id\":\"4182\",\"type\":\"GlyphRenderer\"},\"glyph12\":{\"id\":\"1366\",\"type\":\"GlyphRenderer\"},\"glyph120\":{\"id\":\"4186\",\"type\":\"GlyphRenderer\"},\"glyph121\":{\"id\":\"4190\",\"type\":\"GlyphRenderer\"},\"glyph122\":{\"id\":\"4194\",\"type\":\"GlyphRenderer\"},\"glyph123\":{\"id\":\"4198\",\"type\":\"GlyphRenderer\"},\"glyph124\":{\"id\":\"4202\",\"type\":\"GlyphRenderer\"},\"glyph125\":{\"id\":\"4206\",\"type\":\"GlyphRenderer\"},\"glyph126\":{\"id\":\"4210\",\"type\":\"GlyphRenderer\"},\"glyph127\":{\"id\":\"4214\",\"type\":\"GlyphRenderer\"},\"glyph128\":{\"id\":\"4218\",\"type\":\"GlyphRenderer\"},\"glyph129\":{\"id\":\"4222\",\"type\":\"GlyphRenderer\"},\"glyph13\":{\"id\":\"1370\",\"type\":\"GlyphRenderer\"},\"glyph130\":{\"id\":\"4226\",\"type\":\"GlyphRenderer\"},\"glyph131\":{\"id\":\"4230\",\"type\":\"GlyphRenderer\"},\"glyph14\":{\"id\":\"1374\",\"type\":\"GlyphRenderer\"},\"glyph15\":{\"id\":\"1378\",\"type\":\"GlyphRenderer\"},\"glyph16\":{\"id\":\"1382\",\"type\":\"GlyphRenderer\"},\"glyph17\":{\"id\":\"1386\",\"type\":\"GlyphRenderer\"},\"glyph18\":{\"id\":\"1390\",\"type\":\"GlyphRenderer\"},\"glyph19\":{\"id\":\"1394\",\"type\":\"GlyphRenderer\"},\"glyph2\":{\"id\":\"1125\",\"type\":\"GlyphRenderer\"},\"glyph20\":{\"id\":\"1398\",\"type\":\"GlyphRenderer\"},\"glyph21\":{\"id\":\"1402\",\"type\":\"GlyphRenderer\"},\"glyph22\":{\"id\":\"1406\",\"type\":\"GlyphRenderer\"},\"glyph23\":{\"id\":\"1410\",\"type\":\"GlyphRenderer\"},\"glyph24\":{\"id\":\"1635\",\"type\":\"GlyphRenderer\"},\"glyph25\":{\"id\":\"1639\",\"type\":\"GlyphRenderer\"},\"glyph26\":{\"id\":\"1643\",\"type\":\"GlyphRenderer\"},\"glyph27\":{\"id\":\"1647\",\"type\":\"GlyphRenderer\"},\"glyph28\":{\"id\":\"1651\",\"type\":\"GlyphRenderer\"},\"glyph29\":{\"id\":\"1655\",\"type\":\"GlyphRenderer\"},\"glyph3\":{\"id\":\"1129\",\"type\":\"GlyphRenderer\"},\"glyph30\":{\"id\":\"1659\",\"type\":\"GlyphRenderer\"},\"glyph31\":{\"id\":\"1663\",\"type\":\"GlyphRenderer\"},\"glyph32\":{\"id\":\"1667\",\"type\":\"GlyphRenderer\"},\"glyph33\":{\"id\":\"1671\",\"type\":\"GlyphRenderer\"},\"glyph34\":{\"id\":\"1675\",\"type\":\"GlyphRenderer\"},\"glyph35\":{\"id\":\"1679\",\"type\":\"GlyphRenderer\"},\"glyph36\":{\"id\":\"1924\",\"type\":\"GlyphRenderer\"},\"glyph37\":{\"id\":\"1928\",\"type\":\"GlyphRenderer\"},\"glyph38\":{\"id\":\"1932\",\"type\":\"GlyphRenderer\"},\"glyph39\":{\"id\":\"1936\",\"type\":\"GlyphRenderer\"},\"glyph4\":{\"id\":\"1133\",\"type\":\"GlyphRenderer\"},\"glyph40\":{\"id\":\"1940\",\"type\":\"GlyphRenderer\"},\"glyph41\":{\"id\":\"1944\",\"type\":\"GlyphRenderer\"},\"glyph42\":{\"id\":\"1948\",\"type\":\"GlyphRenderer\"},\"glyph43\":{\"id\":\"1952\",\"type\":\"GlyphRenderer\"},\"glyph44\":{\"id\":\"1956\",\"type\":\"GlyphRenderer\"},\"glyph45\":{\"id\":\"1960\",\"type\":\"GlyphRenderer\"},\"glyph46\":{\"id\":\"1964\",\"type\":\"GlyphRenderer\"},\"glyph47\":{\"id\":\"1968\",\"type\":\"GlyphRenderer\"},\"glyph48\":{\"id\":\"2233\",\"type\":\"GlyphRenderer\"},\"glyph49\":{\"id\":\"2237\",\"type\":\"GlyphRenderer\"},\"glyph5\":{\"id\":\"1137\",\"type\":\"GlyphRenderer\"},\"glyph50\":{\"id\":\"2241\",\"type\":\"GlyphRenderer\"},\"glyph51\":{\"id\":\"2245\",\"type\":\"GlyphRenderer\"},\"glyph52\":{\"id\":\"2249\",\"type\":\"GlyphRenderer\"},\"glyph53\":{\"id\":\"2253\",\"type\":\"GlyphRenderer\"},\"glyph54\":{\"id\":\"2257\",\"type\":\"GlyphRenderer\"},\"glyph55\":{\"id\":\"2261\",\"type\":\"GlyphRenderer\"},\"glyph56\":{\"id\":\"2265\",\"type\":\"GlyphRenderer\"},\"glyph57\":{\"id\":\"2269\",\"type\":\"GlyphRenderer\"},\"glyph58\":{\"id\":\"2273\",\"type\":\"GlyphRenderer\"},\"glyph59\":{\"id\":\"2277\",\"type\":\"GlyphRenderer\"},\"glyph6\":{\"id\":\"1141\",\"type\":\"GlyphRenderer\"},\"glyph60\":{\"id\":\"2562\",\"type\":\"GlyphRenderer\"},\"glyph61\":{\"id\":\"2566\",\"type\":\"GlyphRenderer\"},\"glyph62\":{\"id\":\"2570\",\"type\":\"GlyphRenderer\"},\"glyph63\":{\"id\":\"2574\",\"type\":\"GlyphRenderer\"},\"glyph64\":{\"id\":\"2578\",\"type\":\"GlyphRenderer\"},\"glyph65\":{\"id\":\"2582\",\"type\":\"GlyphRenderer\"},\"glyph66\":{\"id\":\"2586\",\"type\":\"GlyphRenderer\"},\"glyph67\":{\"id\":\"2590\",\"type\":\"GlyphRenderer\"},\"glyph68\":{\"id\":\"2594\",\"type\":\"GlyphRenderer\"},\"glyph69\":{\"id\":\"2598\",\"type\":\"GlyphRenderer\"},\"glyph7\":{\"id\":\"1145\",\"type\":\"GlyphRenderer\"},\"glyph70\":{\"id\":\"2602\",\"type\":\"GlyphRenderer\"},\"glyph71\":{\"id\":\"2606\",\"type\":\"GlyphRenderer\"},\"glyph72\":{\"id\":\"2911\",\"type\":\"GlyphRenderer\"},\"glyph73\":{\"id\":\"2915\",\"type\":\"GlyphRenderer\"},\"glyph74\":{\"id\":\"2919\",\"type\":\"GlyphRenderer\"},\"glyph75\":{\"id\":\"2923\",\"type\":\"GlyphRenderer\"},\"glyph76\":{\"id\":\"2927\",\"type\":\"GlyphRenderer\"},\"glyph77\":{\"id\":\"2931\",\"type\":\"GlyphRenderer\"},\"glyph78\":{\"id\":\"2935\",\"type\":\"GlyphRenderer\"},\"glyph79\":{\"id\":\"2939\",\"type\":\"GlyphRenderer\"},\"glyph8\":{\"id\":\"1149\",\"type\":\"GlyphRenderer\"},\"glyph80\":{\"id\":\"2943\",\"type\":\"GlyphRenderer\"},\"glyph81\":{\"id\":\"2947\",\"type\":\"GlyphRenderer\"},\"glyph82\":{\"id\":\"2951\",\"type\":\"GlyphRenderer\"},\"glyph83\":{\"id\":\"2955\",\"type\":\"GlyphRenderer\"},\"glyph84\":{\"id\":\"3280\",\"type\":\"GlyphRenderer\"},\"glyph85\":{\"id\":\"3284\",\"type\":\"GlyphRenderer\"},\"glyph86\":{\"id\":\"3288\",\"type\":\"GlyphRenderer\"},\"glyph87\":{\"id\":\"3292\",\"type\":\"GlyphRenderer\"},\"glyph88\":{\"id\":\"3296\",\"type\":\"GlyphRenderer\"},\"glyph89\":{\"id\":\"3300\",\"type\":\"GlyphRenderer\"},\"glyph9\":{\"id\":\"1153\",\"type\":\"GlyphRenderer\"},\"glyph90\":{\"id\":\"3304\",\"type\":\"GlyphRenderer\"},\"glyph91\":{\"id\":\"3308\",\"type\":\"GlyphRenderer\"},\"glyph92\":{\"id\":\"3312\",\"type\":\"GlyphRenderer\"},\"glyph93\":{\"id\":\"3316\",\"type\":\"GlyphRenderer\"},\"glyph94\":{\"id\":\"3320\",\"type\":\"GlyphRenderer\"},\"glyph95\":{\"id\":\"3324\",\"type\":\"GlyphRenderer\"},\"glyph96\":{\"id\":\"3669\",\"type\":\"GlyphRenderer\"},\"glyph97\":{\"id\":\"3673\",\"type\":\"GlyphRenderer\"},\"glyph98\":{\"id\":\"3677\",\"type\":\"GlyphRenderer\"},\"glyph99\":{\"id\":\"3681\",\"type\":\"GlyphRenderer\"},\"time_slider\":{\"id\":\"4554\",\"type\":\"Slider\"}},\"code\":\"var glyphs = [glyph0, glyph1, glyph2, glyph3, glyph4, glyph5, glyph6, glyph7, glyph8, glyph9, glyph10, glyph11, glyph12, glyph13, glyph14, glyph15, glyph16, glyph17, glyph18, glyph19, glyph20, glyph21, glyph22, glyph23, glyph24, glyph25, glyph26, glyph27, glyph28, glyph29, glyph30, glyph31, glyph32, glyph33, glyph34, glyph35, glyph36, glyph37, glyph38, glyph39, glyph40, glyph41, glyph42, glyph43, glyph44, glyph45, glyph46, glyph47, glyph48, glyph49, glyph50, glyph51, glyph52, glyph53, glyph54, glyph55, glyph56, glyph57, glyph58, glyph59, glyph60, glyph61, glyph62, glyph63, glyph64, glyph65, glyph66, glyph67, glyph68, glyph69, glyph70, glyph71, glyph72, glyph73, glyph74, glyph75, glyph76, glyph77, glyph78, glyph79, glyph80, glyph81, glyph82, glyph83, glyph84, glyph85, glyph86, glyph87, glyph88, glyph89, glyph90, glyph91, glyph92, glyph93, glyph94, glyph95, glyph96, glyph97, glyph98, glyph99, glyph100, glyph101, glyph102, glyph103, glyph104, glyph105, glyph106, glyph107, glyph108, glyph109, glyph110, glyph111, glyph112, glyph113, glyph114, glyph115, glyph116, glyph117, glyph118, glyph119, glyph120, glyph121, glyph122, glyph123, glyph124, glyph125, glyph126, glyph127, glyph128, glyph129, glyph130, glyph131];var overtime = [[0,1,2,3,4,5,6,7,8,9,10,11],[12,13,14,15,16,17,18,19,20,21,22,23],[24,25,26,27,28,29,30,31,32,33,34,35],[36,37,38,39,40,41,42,43,44,45,46,47],[48,49,50,51,52,53,54,55,56,57,58,59],[60,61,62,63,64,65,66,67,68,69,70,71],[72,73,74,75,76,77,78,79,80,81,82,83],[84,85,86,87,88,89,90,91,92,93,94,95],[96,97,98,99,100,101,102,103,104,105,106,107],[108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131]];var runs = [[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131]];\\n glyphs.forEach(function(g) {\\n g.visible = false;\\n })\\n // union function\\n function union_arrays(x, y) {\\n var obj = {};\\n for (var i = x.length-1; i >= 0; -- i)\\n obj[x[i]] = x[i];\\n for (var i = y.length-1; i >= 0; -- i)\\n obj[y[i]] = y[i];\\n var res = []\\n for (var k in obj) {\\n if (obj.hasOwnProperty(k)) // <-- optional\\n res.push(obj[k]);\\n }\\n return res;\\n }\\n console.log(\\\"Timeslider: \\\" + time_slider.value);\\n console.log(\\\"Checkbox: \\\" + checkbox.active);var slider_labels = ['2.10', '3.20', '4.30', '5.40', '6.50', '7.60', '8.70', '10.90', '15.30', '21.90'];console.log(\\\"Detected slider_labels: \\\" + slider_labels);time_slider.title = \\\"Until wallclocktime \\\" + slider_labels[time_slider.value - 1] + \\\". Step no.\\\"; \\n var activate = [];\\n // if we want multiple checkboxes at the same time, we need to combine the arrays\\n checkbox.active.forEach(function(c) {\\n activate = union_arrays(activate, runs[c]);\\n })\\n // now the intersection of timeslider-activated and checkbox-activated\\n activate = activate.filter(value => -1 !== overtime[time_slider.value - 1].indexOf(value));\\n activate.forEach(function(idx) {\\n glyphs[idx].visible = true;\\n })\\n \"},\"id\":\"4556\",\"type\":\"CustomJS\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]},\"id\":\"4133\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true]},\"id\":\"2896\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4220\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"4130\",\"type\":\"GroupFilter\"},{\"id\":\"4131\",\"type\":\"GroupFilter\"},{\"id\":\"4132\",\"type\":\"GroupFilter\"},{\"id\":\"4133\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"}},\"id\":\"4134\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2895\",\"type\":\"GroupFilter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"3633\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4221\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4136\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4220\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4221\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4124\",\"type\":\"CDSView\"}},\"id\":\"4222\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"red\",\"white\",\"white\",\"white\"],\"origin\":[\"Random\",\"Random\",\"Random\",\"Random\"],\"p_delay\":[\"None\",\"None\",\"None\",\"None\"],\"p_sequence_length\":[1,2,3,4],\"runs\":[1,1,1,1],\"size\":[12.0,12.0,12.0,12.0],\"type\":[\"Final Incumbent\",\"Candidate\",\"Candidate\",\"Candidate\"],\"x\":{\"__ndarray__\":\"9XycTryI4z8V1Y/pH4nVP33uZXS0Jq8/nYRVUx7zyL8=\",\"dtype\":\"float64\",\"shape\":[4]},\"y\":{\"__ndarray__\":\"mzBNdScfwr/cguHH3HPRv8eNZF3Badu/c7FyYAoG478=\",\"dtype\":\"float64\",\"shape\":[4]},\"zorder\":[\"0\",\"0\",\"0\",\"0\"]},\"selected\":{\"id\":\"1697\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1696\",\"type\":\"UnionRenderers\"}},\"id\":\"1003\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"filters\":[{\"id\":\"2848\",\"type\":\"GroupFilter\"},{\"id\":\"2849\",\"type\":\"GroupFilter\"},{\"id\":\"2850\",\"type\":\"GroupFilter\"},{\"id\":\"2851\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"}},\"id\":\"2852\",\"type\":\"CDSView\"},{\"attributes\":{\"filters\":[{\"id\":\"2893\",\"type\":\"GroupFilter\"},{\"id\":\"2894\",\"type\":\"GroupFilter\"},{\"id\":\"2895\",\"type\":\"GroupFilter\"},{\"id\":\"2896\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"}},\"id\":\"2897\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4137\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"2898\",\"type\":\"GroupFilter\"},{\"attributes\":{\"args\":{\"checkbox\":{\"id\":\"4555\",\"type\":\"CheckboxButtonGroup\"},\"glyph0\":{\"id\":\"1117\",\"type\":\"GlyphRenderer\"},\"glyph1\":{\"id\":\"1121\",\"type\":\"GlyphRenderer\"},\"glyph10\":{\"id\":\"1157\",\"type\":\"GlyphRenderer\"},\"glyph100\":{\"id\":\"3685\",\"type\":\"GlyphRenderer\"},\"glyph101\":{\"id\":\"3689\",\"type\":\"GlyphRenderer\"},\"glyph102\":{\"id\":\"3693\",\"type\":\"GlyphRenderer\"},\"glyph103\":{\"id\":\"3697\",\"type\":\"GlyphRenderer\"},\"glyph104\":{\"id\":\"3701\",\"type\":\"GlyphRenderer\"},\"glyph105\":{\"id\":\"3705\",\"type\":\"GlyphRenderer\"},\"glyph106\":{\"id\":\"3709\",\"type\":\"GlyphRenderer\"},\"glyph107\":{\"id\":\"3713\",\"type\":\"GlyphRenderer\"},\"glyph108\":{\"id\":\"4138\",\"type\":\"GlyphRenderer\"},\"glyph109\":{\"id\":\"4142\",\"type\":\"GlyphRenderer\"},\"glyph11\":{\"id\":\"1161\",\"type\":\"GlyphRenderer\"},\"glyph110\":{\"id\":\"4146\",\"type\":\"GlyphRenderer\"},\"glyph111\":{\"id\":\"4150\",\"type\":\"GlyphRenderer\"},\"glyph112\":{\"id\":\"4154\",\"type\":\"GlyphRenderer\"},\"glyph113\":{\"id\":\"4158\",\"type\":\"GlyphRenderer\"},\"glyph114\":{\"id\":\"4162\",\"type\":\"GlyphRenderer\"},\"glyph115\":{\"id\":\"4166\",\"type\":\"GlyphRenderer\"},\"glyph116\":{\"id\":\"4170\",\"type\":\"GlyphRenderer\"},\"glyph117\":{\"id\":\"4174\",\"type\":\"GlyphRenderer\"},\"glyph118\":{\"id\":\"4178\",\"type\":\"GlyphRenderer\"},\"glyph119\":{\"id\":\"4182\",\"type\":\"GlyphRenderer\"},\"glyph12\":{\"id\":\"1366\",\"type\":\"GlyphRenderer\"},\"glyph120\":{\"id\":\"4186\",\"type\":\"GlyphRenderer\"},\"glyph121\":{\"id\":\"4190\",\"type\":\"GlyphRenderer\"},\"glyph122\":{\"id\":\"4194\",\"type\":\"GlyphRenderer\"},\"glyph123\":{\"id\":\"4198\",\"type\":\"GlyphRenderer\"},\"glyph124\":{\"id\":\"4202\",\"type\":\"GlyphRenderer\"},\"glyph125\":{\"id\":\"4206\",\"type\":\"GlyphRenderer\"},\"glyph126\":{\"id\":\"4210\",\"type\":\"GlyphRenderer\"},\"glyph127\":{\"id\":\"4214\",\"type\":\"GlyphRenderer\"},\"glyph128\":{\"id\":\"4218\",\"type\":\"GlyphRenderer\"},\"glyph129\":{\"id\":\"4222\",\"type\":\"GlyphRenderer\"},\"glyph13\":{\"id\":\"1370\",\"type\":\"GlyphRenderer\"},\"glyph130\":{\"id\":\"4226\",\"type\":\"GlyphRenderer\"},\"glyph131\":{\"id\":\"4230\",\"type\":\"GlyphRenderer\"},\"glyph14\":{\"id\":\"1374\",\"type\":\"GlyphRenderer\"},\"glyph15\":{\"id\":\"1378\",\"type\":\"GlyphRenderer\"},\"glyph16\":{\"id\":\"1382\",\"type\":\"GlyphRenderer\"},\"glyph17\":{\"id\":\"1386\",\"type\":\"GlyphRenderer\"},\"glyph18\":{\"id\":\"1390\",\"type\":\"GlyphRenderer\"},\"glyph19\":{\"id\":\"1394\",\"type\":\"GlyphRenderer\"},\"glyph2\":{\"id\":\"1125\",\"type\":\"GlyphRenderer\"},\"glyph20\":{\"id\":\"1398\",\"type\":\"GlyphRenderer\"},\"glyph21\":{\"id\":\"1402\",\"type\":\"GlyphRenderer\"},\"glyph22\":{\"id\":\"1406\",\"type\":\"GlyphRenderer\"},\"glyph23\":{\"id\":\"1410\",\"type\":\"GlyphRenderer\"},\"glyph24\":{\"id\":\"1635\",\"type\":\"GlyphRenderer\"},\"glyph25\":{\"id\":\"1639\",\"type\":\"GlyphRenderer\"},\"glyph26\":{\"id\":\"1643\",\"type\":\"GlyphRenderer\"},\"glyph27\":{\"id\":\"1647\",\"type\":\"GlyphRenderer\"},\"glyph28\":{\"id\":\"1651\",\"type\":\"GlyphRenderer\"},\"glyph29\":{\"id\":\"1655\",\"type\":\"GlyphRenderer\"},\"glyph3\":{\"id\":\"1129\",\"type\":\"GlyphRenderer\"},\"glyph30\":{\"id\":\"1659\",\"type\":\"GlyphRenderer\"},\"glyph31\":{\"id\":\"1663\",\"type\":\"GlyphRenderer\"},\"glyph32\":{\"id\":\"1667\",\"type\":\"GlyphRenderer\"},\"glyph33\":{\"id\":\"1671\",\"type\":\"GlyphRenderer\"},\"glyph34\":{\"id\":\"1675\",\"type\":\"GlyphRenderer\"},\"glyph35\":{\"id\":\"1679\",\"type\":\"GlyphRenderer\"},\"glyph36\":{\"id\":\"1924\",\"type\":\"GlyphRenderer\"},\"glyph37\":{\"id\":\"1928\",\"type\":\"GlyphRenderer\"},\"glyph38\":{\"id\":\"1932\",\"type\":\"GlyphRenderer\"},\"glyph39\":{\"id\":\"1936\",\"type\":\"GlyphRenderer\"},\"glyph4\":{\"id\":\"1133\",\"type\":\"GlyphRenderer\"},\"glyph40\":{\"id\":\"1940\",\"type\":\"GlyphRenderer\"},\"glyph41\":{\"id\":\"1944\",\"type\":\"GlyphRenderer\"},\"glyph42\":{\"id\":\"1948\",\"type\":\"GlyphRenderer\"},\"glyph43\":{\"id\":\"1952\",\"type\":\"GlyphRenderer\"},\"glyph44\":{\"id\":\"1956\",\"type\":\"GlyphRenderer\"},\"glyph45\":{\"id\":\"1960\",\"type\":\"GlyphRenderer\"},\"glyph46\":{\"id\":\"1964\",\"type\":\"GlyphRenderer\"},\"glyph47\":{\"id\":\"1968\",\"type\":\"GlyphRenderer\"},\"glyph48\":{\"id\":\"2233\",\"type\":\"GlyphRenderer\"},\"glyph49\":{\"id\":\"2237\",\"type\":\"GlyphRenderer\"},\"glyph5\":{\"id\":\"1137\",\"type\":\"GlyphRenderer\"},\"glyph50\":{\"id\":\"2241\",\"type\":\"GlyphRenderer\"},\"glyph51\":{\"id\":\"2245\",\"type\":\"GlyphRenderer\"},\"glyph52\":{\"id\":\"2249\",\"type\":\"GlyphRenderer\"},\"glyph53\":{\"id\":\"2253\",\"type\":\"GlyphRenderer\"},\"glyph54\":{\"id\":\"2257\",\"type\":\"GlyphRenderer\"},\"glyph55\":{\"id\":\"2261\",\"type\":\"GlyphRenderer\"},\"glyph56\":{\"id\":\"2265\",\"type\":\"GlyphRenderer\"},\"glyph57\":{\"id\":\"2269\",\"type\":\"GlyphRenderer\"},\"glyph58\":{\"id\":\"2273\",\"type\":\"GlyphRenderer\"},\"glyph59\":{\"id\":\"2277\",\"type\":\"GlyphRenderer\"},\"glyph6\":{\"id\":\"1141\",\"type\":\"GlyphRenderer\"},\"glyph60\":{\"id\":\"2562\",\"type\":\"GlyphRenderer\"},\"glyph61\":{\"id\":\"2566\",\"type\":\"GlyphRenderer\"},\"glyph62\":{\"id\":\"2570\",\"type\":\"GlyphRenderer\"},\"glyph63\":{\"id\":\"2574\",\"type\":\"GlyphRenderer\"},\"glyph64\":{\"id\":\"2578\",\"type\":\"GlyphRenderer\"},\"glyph65\":{\"id\":\"2582\",\"type\":\"GlyphRenderer\"},\"glyph66\":{\"id\":\"2586\",\"type\":\"GlyphRenderer\"},\"glyph67\":{\"id\":\"2590\",\"type\":\"GlyphRenderer\"},\"glyph68\":{\"id\":\"2594\",\"type\":\"GlyphRenderer\"},\"glyph69\":{\"id\":\"2598\",\"type\":\"GlyphRenderer\"},\"glyph7\":{\"id\":\"1145\",\"type\":\"GlyphRenderer\"},\"glyph70\":{\"id\":\"2602\",\"type\":\"GlyphRenderer\"},\"glyph71\":{\"id\":\"2606\",\"type\":\"GlyphRenderer\"},\"glyph72\":{\"id\":\"2911\",\"type\":\"GlyphRenderer\"},\"glyph73\":{\"id\":\"2915\",\"type\":\"GlyphRenderer\"},\"glyph74\":{\"id\":\"2919\",\"type\":\"GlyphRenderer\"},\"glyph75\":{\"id\":\"2923\",\"type\":\"GlyphRenderer\"},\"glyph76\":{\"id\":\"2927\",\"type\":\"GlyphRenderer\"},\"glyph77\":{\"id\":\"2931\",\"type\":\"GlyphRenderer\"},\"glyph78\":{\"id\":\"2935\",\"type\":\"GlyphRenderer\"},\"glyph79\":{\"id\":\"2939\",\"type\":\"GlyphRenderer\"},\"glyph8\":{\"id\":\"1149\",\"type\":\"GlyphRenderer\"},\"glyph80\":{\"id\":\"2943\",\"type\":\"GlyphRenderer\"},\"glyph81\":{\"id\":\"2947\",\"type\":\"GlyphRenderer\"},\"glyph82\":{\"id\":\"2951\",\"type\":\"GlyphRenderer\"},\"glyph83\":{\"id\":\"2955\",\"type\":\"GlyphRenderer\"},\"glyph84\":{\"id\":\"3280\",\"type\":\"GlyphRenderer\"},\"glyph85\":{\"id\":\"3284\",\"type\":\"GlyphRenderer\"},\"glyph86\":{\"id\":\"3288\",\"type\":\"GlyphRenderer\"},\"glyph87\":{\"id\":\"3292\",\"type\":\"GlyphRenderer\"},\"glyph88\":{\"id\":\"3296\",\"type\":\"GlyphRenderer\"},\"glyph89\":{\"id\":\"3300\",\"type\":\"GlyphRenderer\"},\"glyph9\":{\"id\":\"1153\",\"type\":\"GlyphRenderer\"},\"glyph90\":{\"id\":\"3304\",\"type\":\"GlyphRenderer\"},\"glyph91\":{\"id\":\"3308\",\"type\":\"GlyphRenderer\"},\"glyph92\":{\"id\":\"3312\",\"type\":\"GlyphRenderer\"},\"glyph93\":{\"id\":\"3316\",\"type\":\"GlyphRenderer\"},\"glyph94\":{\"id\":\"3320\",\"type\":\"GlyphRenderer\"},\"glyph95\":{\"id\":\"3324\",\"type\":\"GlyphRenderer\"},\"glyph96\":{\"id\":\"3669\",\"type\":\"GlyphRenderer\"},\"glyph97\":{\"id\":\"3673\",\"type\":\"GlyphRenderer\"},\"glyph98\":{\"id\":\"3677\",\"type\":\"GlyphRenderer\"},\"glyph99\":{\"id\":\"3681\",\"type\":\"GlyphRenderer\"},\"time_slider\":{\"id\":\"4554\",\"type\":\"Slider\"}},\"code\":\"checkbox.active = [0];var glyphs = [glyph0, glyph1, glyph2, glyph3, glyph4, glyph5, glyph6, glyph7, glyph8, glyph9, glyph10, glyph11, glyph12, glyph13, glyph14, glyph15, glyph16, glyph17, glyph18, glyph19, glyph20, glyph21, glyph22, glyph23, glyph24, glyph25, glyph26, glyph27, glyph28, glyph29, glyph30, glyph31, glyph32, glyph33, glyph34, glyph35, glyph36, glyph37, glyph38, glyph39, glyph40, glyph41, glyph42, glyph43, glyph44, glyph45, glyph46, glyph47, glyph48, glyph49, glyph50, glyph51, glyph52, glyph53, glyph54, glyph55, glyph56, glyph57, glyph58, glyph59, glyph60, glyph61, glyph62, glyph63, glyph64, glyph65, glyph66, glyph67, glyph68, glyph69, glyph70, glyph71, glyph72, glyph73, glyph74, glyph75, glyph76, glyph77, glyph78, glyph79, glyph80, glyph81, glyph82, glyph83, glyph84, glyph85, glyph86, glyph87, glyph88, glyph89, glyph90, glyph91, glyph92, glyph93, glyph94, glyph95, glyph96, glyph97, glyph98, glyph99, glyph100, glyph101, glyph102, glyph103, glyph104, glyph105, glyph106, glyph107, glyph108, glyph109, glyph110, glyph111, glyph112, glyph113, glyph114, glyph115, glyph116, glyph117, glyph118, glyph119, glyph120, glyph121, glyph122, glyph123, glyph124, glyph125, glyph126, glyph127, glyph128, glyph129, glyph130, glyph131];var overtime = [[0,1,2,3,4,5,6,7,8,9,10,11],[12,13,14,15,16,17,18,19,20,21,22,23],[24,25,26,27,28,29,30,31,32,33,34,35],[36,37,38,39,40,41,42,43,44,45,46,47],[48,49,50,51,52,53,54,55,56,57,58,59],[60,61,62,63,64,65,66,67,68,69,70,71],[72,73,74,75,76,77,78,79,80,81,82,83],[84,85,86,87,88,89,90,91,92,93,94,95],[96,97,98,99,100,101,102,103,104,105,106,107],[108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131]];var runs = [[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131]];\\n glyphs.forEach(function(g) {\\n g.visible = false;\\n })\\n // union function\\n function union_arrays(x, y) {\\n var obj = {};\\n for (var i = x.length-1; i >= 0; -- i)\\n obj[x[i]] = x[i];\\n for (var i = y.length-1; i >= 0; -- i)\\n obj[y[i]] = y[i];\\n var res = []\\n for (var k in obj) {\\n if (obj.hasOwnProperty(k)) // <-- optional\\n res.push(obj[k]);\\n }\\n return res;\\n }\\n console.log(\\\"Timeslider: \\\" + time_slider.value);\\n console.log(\\\"Checkbox: \\\" + checkbox.active);var slider_labels = ['2.10', '3.20', '4.30', '5.40', '6.50', '7.60', '8.70', '10.90', '15.30', '21.90'];console.log(\\\"Detected slider_labels: \\\" + slider_labels);time_slider.title = \\\"Until wallclocktime \\\" + slider_labels[time_slider.value - 1] + \\\". Step no.\\\"; \\n var activate = [];\\n // if we want multiple checkboxes at the same time, we need to combine the arrays\\n checkbox.active.forEach(function(c) {\\n activate = union_arrays(activate, runs[c]);\\n })\\n // now the intersection of timeslider-activated and checkbox-activated\\n activate = activate.filter(value => -1 !== overtime[time_slider.value - 1].indexOf(value));\\n activate.forEach(function(idx) {\\n glyphs[idx].visible = true;\\n })\\n \"},\"id\":\"4558\",\"type\":\"CustomJS\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4136\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4137\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4019\",\"type\":\"CDSView\"}},\"id\":\"4138\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4224\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4225\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Random\"},\"id\":\"2899\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"inverted_triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4204\",\"type\":\"Scatter\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4224\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4225\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4129\",\"type\":\"CDSView\"}},\"id\":\"4226\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4140\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2900\",\"type\":\"GroupFilter\"},{\"attributes\":{\"callback\":null,\"data\":{\"color\":[\"red\",\"white\"],\"origin\":[\"Random\",\"Random\"],\"p_delay\":[\"None\",\"None\"],\"p_sequence_length\":[1,2],\"runs\":[1,1],\"size\":[12.0,12.0],\"type\":[\"Final Incumbent\",\"Candidate\"],\"x\":{\"__ndarray__\":\"9XycTryI4z8V1Y/pH4nVPw==\",\"dtype\":\"float64\",\"shape\":[2]},\"y\":{\"__ndarray__\":\"mzBNdScfwr/cguHH3HPRvw==\",\"dtype\":\"float64\",\"shape\":[2]},\"zorder\":[\"0\",\"0\"]},\"selected\":{\"id\":\"1175\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"1174\",\"type\":\"UnionRenderers\"}},\"id\":\"1001\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4141\",\"type\":\"Scatter\"},{\"attributes\":{\"callback\":{\"id\":\"4558\",\"type\":\"CustomJS\"},\"icon\":null,\"label\":\"All\"},\"id\":\"4559\",\"type\":\"Button\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true]},\"id\":\"2901\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4140\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4141\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4024\",\"type\":\"CDSView\"}},\"id\":\"4142\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"filters\":[{\"id\":\"2898\",\"type\":\"GroupFilter\"},{\"id\":\"2899\",\"type\":\"GroupFilter\"},{\"id\":\"2900\",\"type\":\"GroupFilter\"},{\"id\":\"2901\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1007\",\"type\":\"ColumnDataSource\"}},\"id\":\"2902\",\"type\":\"CDSView\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4228\",\"type\":\"Scatter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"marker\":{\"value\":\"triangle\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4229\",\"type\":\"Scatter\"},{\"attributes\":{\"column_name\":\"type\",\"group\":\"Default\"},\"id\":\"2903\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4228\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4229\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4134\",\"type\":\"CDSView\"}},\"id\":\"4230\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"fill_color\":{\"field\":\"color\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4144\",\"type\":\"Scatter\"},{\"attributes\":{\"filters\":[{\"id\":\"2499\",\"type\":\"GroupFilter\"},{\"id\":\"2500\",\"type\":\"GroupFilter\"},{\"id\":\"2501\",\"type\":\"GroupFilter\"},{\"id\":\"2502\",\"type\":\"BooleanFilter\"}],\"source\":{\"id\":\"1006\",\"type\":\"ColumnDataSource\"}},\"id\":\"2503\",\"type\":\"CDSView\"},{\"attributes\":{\"column_name\":\"origin\",\"group\":\"Acquisition Function\"},\"id\":\"2904\",\"type\":\"GroupFilter\"},{\"attributes\":{\"fill_alpha\":{\"value\":0.1},\"fill_color\":{\"value\":\"#1f77b4\"},\"line_alpha\":{\"value\":0.1},\"line_color\":{\"value\":\"#1f77b4\"},\"size\":{\"field\":\"size\",\"units\":\"screen\"},\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"4145\",\"type\":\"Scatter\"},{\"attributes\":{},\"id\":\"2298\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"column_name\":\"zorder\",\"group\":\"0\"},\"id\":\"2905\",\"type\":\"GroupFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4144\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4145\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4029\",\"type\":\"CDSView\"}},\"id\":\"4146\",\"type\":\"GlyphRenderer\"},{\"attributes\":{},\"id\":\"2299\",\"type\":\"Selection\"},{\"attributes\":{\"booleans\":[true,true,true,true,true,true,true,true]},\"id\":\"2906\",\"type\":\"BooleanFilter\"},{\"attributes\":{\"data_source\":{\"id\":\"1010\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"4200\",\"type\":\"Scatter\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"4201\",\"type\":\"Scatter\"},\"selection_glyph\":null,\"view\":{\"id\":\"4099\",\"type\":\"CDSView\"}},\"id\":\"4202\",\"type\":\"GlyphRenderer\"}],\"root_ids\":[\"4575\"]},\"title\":\"Bokeh Application\",\"version\":\"1.1.0\"}};\n", - " var render_items = [{\"docid\":\"06bbb144-6c77-4643-bce0-9a725c3d0ad9\",\"roots\":{\"4575\":\"c1c87f82-af72-4478-b825-77e6d526594c\"}}];\n", - " root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", - "\n", - " }\n", - " if (root.Bokeh !== undefined) {\n", - " embed_document(root);\n", - " } else {\n", - " var attempts = 0;\n", - " var timer = setInterval(function(root) {\n", - " if (root.Bokeh !== undefined) {\n", - " embed_document(root);\n", - " clearInterval(timer);\n", - " }\n", - " attempts++;\n", - " if (attempts > 100) {\n", - " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n", - " clearInterval(timer);\n", - " }\n", - " }, 10, root)\n", - " }\n", - "})(window);" - ], - "application/vnd.bokehjs_exec.v0+json": "" - }, - "metadata": { - "application/vnd.bokehjs_exec.v0+json": { - "id": "4575" - } - }, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cave.configurator_footprint()" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [], - "source": [ - "#won't show \n", - "cave.feature_importance()" - ] - }, - { - "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "cave.algorithm_footprints()" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "
\n", - " \n", - " Loading BokehJS ...\n", - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "\n", - "(function(root) {\n", - " function now() {\n", - " return new Date();\n", - " }\n", - "\n", - " var force = true;\n", - "\n", - " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", - " root._bokeh_onload_callbacks = [];\n", - " root._bokeh_is_loading = undefined;\n", - " }\n", - "\n", - " var JS_MIME_TYPE = 'application/javascript';\n", - " var HTML_MIME_TYPE = 'text/html';\n", - " var EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n", - " var CLASS_NAME = 'output_bokeh rendered_html';\n", - "\n", - " /**\n", - " * Render data to the DOM node\n", - " */\n", - " function render(props, node) {\n", - " var script = document.createElement(\"script\");\n", - " node.appendChild(script);\n", - " }\n", - "\n", - " /**\n", - " * Handle when an output is cleared or removed\n", - " */\n", - " function handleClearOutput(event, handle) {\n", - " var cell = handle.cell;\n", - "\n", - " var id = cell.output_area._bokeh_element_id;\n", - " var server_id = cell.output_area._bokeh_server_id;\n", - " // Clean up Bokeh references\n", - " if (id != null && id in Bokeh.index) {\n", - " Bokeh.index[id].model.document.clear();\n", - " delete Bokeh.index[id];\n", - " }\n", - "\n", - " if (server_id !== undefined) {\n", - " // Clean up Bokeh references\n", - " var cmd = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n", - " cell.notebook.kernel.execute(cmd, {\n", - " iopub: {\n", - " output: function(msg) {\n", - " var id = msg.content.text.trim();\n", - " if (id in Bokeh.index) {\n", - " Bokeh.index[id].model.document.clear();\n", - " delete Bokeh.index[id];\n", - " }\n", - " }\n", - " }\n", - " });\n", - " // Destroy server and session\n", - " var cmd = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n", - " cell.notebook.kernel.execute(cmd);\n", - " }\n", - " }\n", - "\n", - " /**\n", - " * Handle when a new output is added\n", - " */\n", - " function handleAddOutput(event, handle) {\n", - " var output_area = handle.output_area;\n", - " var output = handle.output;\n", - "\n", - " // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n", - " if ((output.output_type != \"display_data\") || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", - " return\n", - " }\n", - "\n", - " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", - "\n", - " if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n", - " toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n", - " // store reference to embed id on output_area\n", - " output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", - " }\n", - " if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", - " var bk_div = document.createElement(\"div\");\n", - " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", - " var script_attrs = bk_div.children[0].attributes;\n", - " for (var i = 0; i < script_attrs.length; i++) {\n", - " toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n", - " }\n", - " // store reference to server id on output_area\n", - " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", - " }\n", - " }\n", - "\n", - " function register_renderer(events, OutputArea) {\n", - "\n", - " function append_mime(data, metadata, element) {\n", - " // create a DOM node to render to\n", - " var toinsert = this.create_output_subarea(\n", - " metadata,\n", - " CLASS_NAME,\n", - " EXEC_MIME_TYPE\n", - " );\n", - " this.keyboard_manager.register_events(toinsert);\n", - " // Render to node\n", - " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", - " render(props, toinsert[toinsert.length - 1]);\n", - " element.append(toinsert);\n", - " return toinsert\n", - " }\n", - "\n", - " /* Handle when an output is cleared or removed */\n", - " events.on('clear_output.CodeCell', handleClearOutput);\n", - " events.on('delete.Cell', handleClearOutput);\n", - "\n", - " /* Handle when a new output is added */\n", - " events.on('output_added.OutputArea', handleAddOutput);\n", - "\n", - " /**\n", - " * Register the mime type and append_mime function with output_area\n", - " */\n", - " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", - " /* Is output safe? */\n", - " safe: true,\n", - " /* Index of renderer in `output_area.display_order` */\n", - " index: 0\n", - " });\n", - " }\n", - "\n", - " // register the mime type if in Jupyter Notebook environment and previously unregistered\n", - " if (root.Jupyter !== undefined) {\n", - " var events = require('base/js/events');\n", - " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", - "\n", - " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", - " register_renderer(events, OutputArea);\n", - " }\n", - " }\n", - "\n", - " \n", - " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", - " root._bokeh_timeout = Date.now() + 5000;\n", - " root._bokeh_failed_load = false;\n", - " }\n", - "\n", - " var NB_LOAD_WARNING = {'data': {'text/html':\n", - " \"
\\n\"+\n", - " \"

\\n\"+\n", - " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", - " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", - " \"

\\n\"+\n", - " \"
    \\n\"+\n", - " \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n", - " \"
  • use INLINE resources instead, as so:
  • \\n\"+\n", - " \"
\\n\"+\n", - " \"\\n\"+\n", - " \"from bokeh.resources import INLINE\\n\"+\n", - " \"output_notebook(resources=INLINE)\\n\"+\n", - " \"\\n\"+\n", - " \"
\"}};\n", - "\n", - " function display_loaded() {\n", - " var el = document.getElementById(\"5122\");\n", - " if (el != null) {\n", - " el.textContent = \"BokehJS is loading...\";\n", - " }\n", - " if (root.Bokeh !== undefined) {\n", - " if (el != null) {\n", - " el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n", - " }\n", - " } else if (Date.now() < root._bokeh_timeout) {\n", - " setTimeout(display_loaded, 100)\n", - " }\n", - " }\n", - "\n", - "\n", - " function run_callbacks() {\n", - " try {\n", - " root._bokeh_onload_callbacks.forEach(function(callback) {\n", - " if (callback != null)\n", - " callback();\n", - " });\n", - " } finally {\n", - " delete root._bokeh_onload_callbacks\n", - " }\n", - " console.debug(\"Bokeh: all callbacks have finished\");\n", - " }\n", - "\n", - " function load_libs(css_urls, js_urls, callback) {\n", - " if (css_urls == null) css_urls = [];\n", - " if (js_urls == null) js_urls = [];\n", - "\n", - " root._bokeh_onload_callbacks.push(callback);\n", - " if (root._bokeh_is_loading > 0) {\n", - " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", - " return null;\n", - " }\n", - " if (js_urls == null || js_urls.length === 0) {\n", - " run_callbacks();\n", - " return null;\n", - " }\n", - " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", - " root._bokeh_is_loading = css_urls.length + js_urls.length;\n", - "\n", - " function on_load() {\n", - " root._bokeh_is_loading--;\n", - " if (root._bokeh_is_loading === 0) {\n", - " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", - " run_callbacks()\n", - " }\n", - " }\n", - "\n", - " function on_error() {\n", - " console.error(\"failed to load \" + url);\n", - " }\n", - "\n", - " for (var i = 0; i < css_urls.length; i++) {\n", - " var url = css_urls[i];\n", - " const element = document.createElement(\"link\");\n", - " element.onload = on_load;\n", - " element.onerror = on_error;\n", - " element.rel = \"stylesheet\";\n", - " element.type = \"text/css\";\n", - " element.href = url;\n", - " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", - " document.body.appendChild(element);\n", - " }\n", - "\n", - " for (var i = 0; i < js_urls.length; i++) {\n", - " var url = js_urls[i];\n", - " var element = document.createElement('script');\n", - " element.onload = on_load;\n", - " element.onerror = on_error;\n", - " element.async = false;\n", - " element.src = url;\n", - " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", - " document.head.appendChild(element);\n", - " }\n", - " };var element = document.getElementById(\"5122\");\n", - " if (element == null) {\n", - " console.error(\"Bokeh: ERROR: autoload.js configured with elementid '5122' but no matching script tag was found. \")\n", - " return false;\n", - " }\n", - "\n", - " function inject_raw_css(css) {\n", - " const element = document.createElement(\"style\");\n", - " element.appendChild(document.createTextNode(css));\n", - " document.body.appendChild(element);\n", - " }\n", - "\n", - " var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.1.0.min.js\"];\n", - " var css_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.css\"];\n", - "\n", - " var inline_js = [\n", - " function(Bokeh) {\n", - " Bokeh.set_log_level(\"info\");\n", - " },\n", - " \n", - " function(Bokeh) {\n", - " (function(root, factory) {\n", - " // if(typeof exports === 'object' && typeof module === 'object')\n", - " // factory(require(\"Bokeh\"));\n", - " // else if(typeof define === 'function' && define.amd)\n", - " // define([\"Bokeh\"], factory);\n", - " // else if(typeof exports === 'object')\n", - " // factory(require(\"Bokeh\"));\n", - " // else\n", - " factory(root[\"Bokeh\"]);\n", - " })(this, function(Bokeh) {\n", - " var define;\n", - " return (function outer(modules, entry) {\n", - " if (Bokeh != null) {\n", - " return Bokeh.register_plugin(modules, {}, entry);\n", - " } else {\n", - " throw new Error(\"Cannot find Bokeh. You have to load it prior to loading plugins.\");\n", - " }\n", - " })\n", - " ({\n", - " \"custom/main\": function(require, module, exports) {\n", - " var models = {\n", - " \"ParallelResetTool\": require(\"custom/cave.plot.parallel_plot.parallel_reset.parallel_reset_tool\").ParallelResetTool,\n", - " \"ParallelSelectionTool\": require(\"custom/cave.plot.parallel_plot.parallel_selection_tool.parallel_selection_tool\").ParallelSelectionTool\n", - " };\n", - " require(\"base\").register_models(models);\n", - " module.exports = models;\n", - " },\n", - " \"custom/cave.plot.parallel_plot.parallel_reset.parallel_reset_tool\": function(require, module, exports) {\n", - " \"use strict\";\n", - " var __extends = (this && this.__extends) || (function () {\n", - " var extendStatics = function (d, b) {\n", - " extendStatics = Object.setPrototypeOf ||\n", - " ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n", - " function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n", - " return extendStatics(d, b);\n", - " };\n", - " return function (d, b) {\n", - " extendStatics(d, b);\n", - " function __() { this.constructor = d; }\n", - " d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n", - " };\n", - " })();\n", - " Object.defineProperty(exports, \"__esModule\", { value: true });\n", - " var action_tool_1 = require(\"models/tools/actions/action_tool\");\n", - " var ParallelResetToolView = /** @class */ (function (_super) {\n", - " __extends(ParallelResetToolView, _super);\n", - " function ParallelResetToolView() {\n", - " return _super !== null && _super.apply(this, arguments) || this;\n", - " }\n", - " ParallelResetToolView.prototype.doit = function () {\n", - " this.plot_view.reset_range();\n", - " };\n", - " return ParallelResetToolView;\n", - " }(action_tool_1.ActionToolView));\n", - " exports.ParallelResetToolView = ParallelResetToolView;\n", - " var ParallelResetTool = /** @class */ (function (_super) {\n", - " __extends(ParallelResetTool, _super);\n", - " function ParallelResetTool(attrs) {\n", - " var _this = _super.call(this, attrs) || this;\n", - " _this.tool_name = \"Reset Zoom\";\n", - " _this.icon = \"bk-tool-icon-reset\";\n", - " return _this;\n", - " }\n", - " ParallelResetTool.initClass = function () {\n", - " this.prototype.type = \"ParallelResetTool\";\n", - " this.prototype.default_view = ParallelResetToolView;\n", - " };\n", - " return ParallelResetTool;\n", - " }(action_tool_1.ActionTool));\n", - " exports.ParallelResetTool = ParallelResetTool;\n", - " ParallelResetTool.initClass();\n", - "\n", - " },\n", - " \"custom/cave.plot.parallel_plot.parallel_selection_tool.parallel_selection_tool\": function(require, module, exports) {\n", - " \"use strict\";\n", - " var __extends = (this && this.__extends) || (function () {\n", - " var extendStatics = function (d, b) {\n", - " extendStatics = Object.setPrototypeOf ||\n", - " ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n", - " function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n", - " return extendStatics(d, b);\n", - " };\n", - " return function (d, b) {\n", - " extendStatics(d, b);\n", - " function __() { this.constructor = d; }\n", - " d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n", - " };\n", - " })();\n", - " Object.defineProperty(exports, \"__esModule\", { value: true });\n", - " var p = require(\"core/properties\");\n", - " var box_select_tool_1 = require(\"models/tools/gestures/box_select_tool\");\n", - " var array_1 = require(\"core/util/array\");\n", - " var dom_1 = require(\"core/dom\");\n", - " function find_indices_in(array, _a) {\n", - " var inf = _a[0], sup = _a[1];\n", - " return array.reduce(function (prev, curr, index) {\n", - " return (inf <= curr && curr <= sup) ? prev.concat(index) : prev;\n", - " }, []);\n", - " }\n", - " function index_array(array, indices) {\n", - " return indices.reduce(function (a, i) { return a.concat(array[i]); }, []);\n", - " }\n", - " function combineByKey(key, array) {\n", - " var keys = Object.keys(array[0]);\n", - " var combined = [];\n", - " array.forEach(function (itm) {\n", - " var idx = combined.map(function (item) { return item[key]; }).indexOf(itm[key]);\n", - " if (idx >= 0) {\n", - " keys.forEach(function (element) {\n", - " if (element != key)\n", - " combined[idx][element].push(itm[element]);\n", - " });\n", - " }\n", - " else {\n", - " var new_object_1 = {};\n", - " keys.forEach(function (element) {\n", - " if (element == key) {\n", - " new_object_1[element] = itm[element];\n", - " }\n", - " else {\n", - " new_object_1[element] = [itm[element]];\n", - " }\n", - " });\n", - " combined.push(new_object_1);\n", - " }\n", - " });\n", - " return combined;\n", - " }\n", - " var ParallelSelectionView = /** @class */ (function (_super) {\n", - " __extends(ParallelSelectionView, _super);\n", - " function ParallelSelectionView() {\n", - " var _this = _super !== null && _super.apply(this, arguments) || this;\n", - " _this.selection_mode = \"add\";\n", - " _this.panning = false;\n", - " return _this;\n", - " }\n", - " ParallelSelectionView.prototype.initialize = function () {\n", - " var _this = this;\n", - " _super.prototype.initialize.call(this);\n", - " var frame = this.plot_view.frame;\n", - " var _a = this.model.renderer_select, x_range_name_select = _a.x_range_name, y_range_name_select = _a.y_range_name;\n", - " var _b = this.model.renderer_data, x_range_name_data = _b.x_range_name, y_range_name_data = _b.y_range_name;\n", - " if (x_range_name_select == x_range_name_data && y_range_name_select == y_range_name_data) {\n", - " this.xscale = frame.xscales[x_range_name_select];\n", - " this.yscale = frame.yscales[y_range_name_select];\n", - " }\n", - " else\n", - " throw new Error(\"selection and data does not share the same ranges\");\n", - " //TODO test if parallel CDS is valid (xs for each line should be identical)\n", - " this.glyph_select = this.model.renderer_select.glyph;\n", - " this.glyph_data = this.model.renderer_data.glyph;\n", - " this.cds_select = this.model.renderer_select.data_source;\n", - " this.cds_data = this.model.renderer_data.data_source;\n", - " var _c = [this.glyph_data.xs.field, this.glyph_data.ys.field], xskey = _c[0], yskey = _c[1];\n", - " this.xdata = this.cds_data.get_array(xskey)[0];\n", - " this.ydataT = array_1.transpose(this.cds_data.get_array(yskey));\n", - " this.selection_indices = [];\n", - " this.connect(this.plot_view.frame.x_ranges[this.model.renderer_select.x_range_name].change, function () { return _this._resize_boxes_on_zoom(); });\n", - " this.connect(this.cds_select.change, function () { return _this._update_data_selection(); });\n", - " };\n", - " Object.defineProperty(ParallelSelectionView.prototype, \"_box_width\", {\n", - " get: function () {\n", - " return this.xscale.invert(this.model.box_width) - this.xscale.invert(0);\n", - " },\n", - " enumerable: true,\n", - " configurable: true\n", - " });\n", - " Object.defineProperty(ParallelSelectionView.prototype, \"_cds_select_keys\", {\n", - " get: function () {\n", - " var glyph_select = this.glyph_select;\n", - " var _a = [glyph_select.x.field, glyph_select.y.field], xkey = _a[0], ykey = _a[1];\n", - " var _b = [glyph_select.width.field, glyph_select.height.field], wkey = _b[0], hkey = _b[1];\n", - " return { xkey: xkey, ykey: ykey, wkey: wkey, hkey: hkey };\n", - " },\n", - " enumerable: true,\n", - " configurable: true\n", - " });\n", - " ParallelSelectionView.prototype._emit_cds_changes = function (cds, redraw, clear, emit) {\n", - " if (redraw === void 0) { redraw = true; }\n", - " if (clear === void 0) { clear = true; }\n", - " if (emit === void 0) { emit = true; }\n", - " if (clear)\n", - " cds.selection_manager.clear();\n", - " if (redraw)\n", - " cds.change.emit();\n", - " if (emit) {\n", - " cds.data = cds.data;\n", - " cds.properties.data.change.emit();\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._box_paramaters = function (index) {\n", - " var _a = this._cds_select_keys, xkey = _a.xkey, ykey = _a.ykey, wkey = _a.wkey, hkey = _a.hkey;\n", - " var x = this.cds_select.get_array(xkey)[index];\n", - " var y = this.cds_select.get_array(ykey)[index];\n", - " var w = this.cds_select.get_array(wkey)[index];\n", - " var h = this.cds_select.get_array(hkey)[index];\n", - " return { x: x, y: y, w: w, h: h };\n", - " };\n", - " ParallelSelectionView.prototype._hit_test_boxes = function (sx, sy) {\n", - " var nboxes = this.cds_select.get_length();\n", - " if (nboxes != 0 && nboxes != null) {\n", - " var _a = [this.xscale.invert(sx), this.yscale.invert(sy)], xtest = _a[0], ytest = _a[1];\n", - " for (var i = 0; i < nboxes; i++) {\n", - " var _b = this._box_paramaters(i), x = _b.x, y = _b.y, w = _b.w, h = _b.h;\n", - " if (xtest >= (x - w / 2) && xtest <= x + w / 2 &&\n", - " ytest >= (y - h / 2) && ytest <= y + h / 2) {\n", - " return i;\n", - " }\n", - " }\n", - " }\n", - " return null;\n", - " };\n", - " ParallelSelectionView.prototype._resize_boxes_on_zoom = function () {\n", - " //resize selection boxes when zooming to keep a constant (pixel) size\n", - " var cds = this.cds_select;\n", - " var array_width = cds.get_array(this.glyph_select.width.field);\n", - " var new_width = this._box_width;\n", - " array_width.forEach(function (_, i) { return array_width[i] = new_width; });\n", - " this._emit_cds_changes(cds, true, false, false);\n", - " };\n", - " ParallelSelectionView.prototype._drag_start = function (ev) {\n", - " //Save y position of the drag start\n", - " if (this.ind_active_box != null) {\n", - " this._base_point = [this.xscale.invert(ev.sx), this.yscale.invert(ev.sy)];\n", - " this._base_box_parameters = this._box_paramaters(this.ind_active_box);\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._update_box_ypos = function (index_box, delta_y) {\n", - " if (this._base_box_parameters != null) {\n", - " var cds = this.cds_select;\n", - " var ykey = this._cds_select_keys.ykey;\n", - " var _a = this._base_box_parameters, current_y = _a.y, h = _a.h;\n", - " var new_y = current_y + delta_y;\n", - " new_y = new_y - Math.max(0, (new_y + h / 2) - 1) - Math.min(0, (new_y - h / 2));\n", - " cds.get_array(ykey)[index_box] = new_y;\n", - " this._emit_cds_changes(cds, true, false, false);\n", - " this._update_selection_indices(index_box, [new_y - h / 2, new_y + h / 2]);\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._drag = function (ev) {\n", - " if (this.ind_active_box != null && this._base_point != null) {\n", - " var delta_y = this.yscale.invert(ev.sy) - this._base_point[1];\n", - " this._update_box_ypos(this.ind_active_box, delta_y);\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._drag_stop = function (_ev) {\n", - " this._base_point = null;\n", - " this._base_box_parameters = null;\n", - " };\n", - " ParallelSelectionView.prototype._pan_start = function (ev) {\n", - " this.panning = true;\n", - " switch (this.selection_mode) {\n", - " case \"add\": {\n", - " _super.prototype._pan_start.call(this, ev);\n", - " break;\n", - " }\n", - " case \"drag\": {\n", - " this._drag_start(ev);\n", - " break;\n", - " }\n", - " case \"resize\": {\n", - " break;\n", - " }\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._pan = function (ev) {\n", - " switch (this.selection_mode) {\n", - " case \"add\": {\n", - " _super.prototype._pan.call(this, ev);\n", - " break;\n", - " }\n", - " case \"drag\": {\n", - " this._drag(ev);\n", - " break;\n", - " }\n", - " case \"resize\": {\n", - " break;\n", - " }\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._pan_end = function (ev) {\n", - " switch (this.selection_mode) {\n", - " case \"add\": {\n", - " _super.prototype._pan_end.call(this, ev);\n", - " break;\n", - " }\n", - " case \"drag\": {\n", - " this._drag_stop(ev);\n", - " break;\n", - " }\n", - " case \"resize\": {\n", - " break;\n", - " }\n", - " }\n", - " this.panning = false;\n", - " };\n", - " ParallelSelectionView.prototype._move = function (ev) {\n", - " //Switch mode\n", - " if (this.panning) {\n", - " return;\n", - " }\n", - " this.ind_active_box = this._hit_test_boxes(ev.sx, ev.sy);\n", - " if (this.ind_active_box != null) {\n", - " this.selection_mode = \"drag\";\n", - " }\n", - " else {\n", - " this.selection_mode = \"add\";\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._doubletap = function (_ev) {\n", - " var _this = this;\n", - " //delete box on double tap\n", - " if (this.ind_active_box != null) {\n", - " this.cds_select.columns().forEach(function (key) {\n", - " _this.cds_select.get_array(key).splice(_this.ind_active_box, 1);\n", - " });\n", - " this._delete_selection_indices(this.ind_active_box);\n", - " this._emit_cds_changes(this.cds_select);\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._keyup = function (ev) {\n", - " var _this = this;\n", - " if (ev.keyCode == dom_1.Keys.Esc) {\n", - " var nelems_1 = this.cds_select.get_length();\n", - " if (nelems_1 != null) {\n", - " this.cds_select.columns().forEach(function (key) {\n", - " _this.cds_select.get_array(key).splice(0, nelems_1);\n", - " });\n", - " this.selection_indices.splice(0, nelems_1);\n", - " this._emit_cds_changes(this.cds_select);\n", - " }\n", - " this.plot_view.request_render();\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._update_data_selection = function () {\n", - " var selection_indices = [];\n", - " if (this.selection_indices.length > 0) {\n", - " var combined_selections = combineByKey('data_idx', this.selection_indices);\n", - " selection_indices = array_1.intersection.apply(void 0, [array_1.union.apply(void 0, combined_selections[0].indices)].concat(combined_selections.slice(1).map(function (elem) { return array_1.union.apply(void 0, elem.indices); })));\n", - " }\n", - " this.cds_data.selected.indices = selection_indices;\n", - " this.cds_data.change.emit();\n", - " };\n", - " ParallelSelectionView.prototype._make_selection_indices = function (indices, _a) {\n", - " var _this = this;\n", - " var _b;\n", - " var y0 = _a[0], y1 = _a[1];\n", - " (_b = this.selection_indices).push.apply(_b, indices.map(function (index) {\n", - " return {\n", - " data_idx: index,\n", - " indices: find_indices_in(_this.ydataT[index], [y0, y1]),\n", - " };\n", - " }));\n", - " };\n", - " ParallelSelectionView.prototype._update_selection_indices = function (index, _a) {\n", - " var y0 = _a[0], y1 = _a[1];\n", - " this.selection_indices[index].indices = find_indices_in(this.ydataT[this.selection_indices[index].data_idx], [y0, y1]);\n", - " };\n", - " ParallelSelectionView.prototype._delete_selection_indices = function (index) {\n", - " this.selection_indices.splice(index, 1);\n", - " };\n", - " ParallelSelectionView.prototype._make_box_select = function (xs, _a) {\n", - " var _this = this;\n", - " var y0 = _a[0], y1 = _a[1];\n", - " y0 = Math.max(0, y0);\n", - " y1 = Math.min(1, y1);\n", - " var y = (y0 + y1) / 2.;\n", - " var w = this._box_width;\n", - " var h = y1 - y0;\n", - " var _b = this._cds_select_keys, xkey = _b.xkey, ykey = _b.ykey, wkey = _b.wkey, hkey = _b.hkey;\n", - " xs.forEach(function (x) {\n", - " if (xkey)\n", - " _this.cds_select.get_array(xkey).push(x);\n", - " if (ykey)\n", - " _this.cds_select.get_array(ykey).push(y);\n", - " if (wkey)\n", - " _this.cds_select.get_array(wkey).push(w);\n", - " if (hkey)\n", - " _this.cds_select.get_array(hkey).push(h);\n", - " });\n", - " this._emit_cds_changes(this.cds_select);\n", - " };\n", - " ParallelSelectionView.prototype._do_select = function (_a, _b, _final, _append) {\n", - " var sx0 = _a[0], sx1 = _a[1];\n", - " var sy0 = _b[0], sy1 = _b[1];\n", - " if (_final === void 0) { _final = true; }\n", - " if (_append === void 0) { _append = true; }\n", - " // Get selection bbox in the data space\n", - " var _c = this.xscale.r_invert(sx0, sx1), x0 = _c[0], x1 = _c[1];\n", - " var _d = this.yscale.r_invert(sy0, sy1), y0 = _d[0], y1 = _d[1];\n", - " var x_indices = find_indices_in(this.xdata, [x0, x1]);\n", - " var xs = index_array(this.xdata, x_indices);\n", - " this._make_selection_indices(x_indices, [y0, y1]);\n", - " this._make_box_select(xs, [y0, y1]);\n", - " };\n", - " return ParallelSelectionView;\n", - " }(box_select_tool_1.BoxSelectToolView));\n", - " exports.ParallelSelectionView = ParallelSelectionView;\n", - " var ParallelSelectionTool = /** @class */ (function (_super) {\n", - " __extends(ParallelSelectionTool, _super);\n", - " function ParallelSelectionTool() {\n", - " var _this = _super !== null && _super.apply(this, arguments) || this;\n", - " _this.tool_name = \"Parallel Selection\";\n", - " //override event_type property define in BoxSelectTool\n", - " _this.event_type = [\"tap\", \"pan\", \"move\"];\n", - " return _this;\n", - " }\n", - " ParallelSelectionTool.initClass = function () {\n", - " this.prototype.type = \"ParallelSelectionTool\";\n", - " this.prototype.default_view = ParallelSelectionView;\n", - " this.define({\n", - " renderer_select: [p.Any],\n", - " renderer_data: [p.Any],\n", - " box_width: [p.Number, 30],\n", - " });\n", - " };\n", - " return ParallelSelectionTool;\n", - " }(box_select_tool_1.BoxSelectTool));\n", - " exports.ParallelSelectionTool = ParallelSelectionTool;\n", - " ParallelSelectionTool.initClass();\n", - "\n", - " }\n", - " }, \"custom/main\");\n", - " ;\n", - " });\n", - "\n", - " },\n", - " function(Bokeh) {} // ensure no trailing comma for IE\n", - " ];\n", - "\n", - " function run_inline_js() {\n", - " \n", - " if ((root.Bokeh !== undefined) || (force === true)) {\n", - " for (var i = 0; i < inline_js.length; i++) {\n", - " inline_js[i].call(root, root.Bokeh);\n", - " }if (force === true) {\n", - " display_loaded();\n", - " }} else if (Date.now() < root._bokeh_timeout) {\n", - " setTimeout(run_inline_js, 100);\n", - " } else if (!root._bokeh_failed_load) {\n", - " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", - " root._bokeh_failed_load = true;\n", - " } else if (force !== true) {\n", - " var cell = $(document.getElementById(\"5122\")).parents('.cell').data().cell;\n", - " cell.output_area.append_execute_result(NB_LOAD_WARNING)\n", - " }\n", - "\n", - " }\n", - "\n", - " if (root._bokeh_is_loading === 0) {\n", - " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", - " run_inline_js();\n", - " } else {\n", - " load_libs(css_urls, js_urls, function() {\n", - " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", - " run_inline_js();\n", - " });\n", - " }\n", - "}(window));" - ], - "application/vnd.bokehjs_load.v0+json": "\n(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n \n\n \n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n var NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n var el = document.getElementById(\"5122\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };var element = document.getElementById(\"5122\");\n if (element == null) {\n console.error(\"Bokeh: ERROR: autoload.js configured with elementid '5122' but no matching script tag was found. \")\n return false;\n }\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.1.0.min.js\"];\n var css_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.css\"];\n\n var inline_js = [\n function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n \n function(Bokeh) {\n (function(root, factory) {\n // if(typeof exports === 'object' && typeof module === 'object')\n // factory(require(\"Bokeh\"));\n // else if(typeof define === 'function' && define.amd)\n // define([\"Bokeh\"], factory);\n // else if(typeof exports === 'object')\n // factory(require(\"Bokeh\"));\n // else\n factory(root[\"Bokeh\"]);\n })(this, function(Bokeh) {\n var define;\n return (function outer(modules, entry) {\n if (Bokeh != null) {\n return Bokeh.register_plugin(modules, {}, entry);\n } else {\n throw new Error(\"Cannot find Bokeh. You have to load it prior to loading plugins.\");\n }\n })\n ({\n \"custom/main\": function(require, module, exports) {\n var models = {\n \"ParallelResetTool\": require(\"custom/cave.plot.parallel_plot.parallel_reset.parallel_reset_tool\").ParallelResetTool,\n \"ParallelSelectionTool\": require(\"custom/cave.plot.parallel_plot.parallel_selection_tool.parallel_selection_tool\").ParallelSelectionTool\n };\n require(\"base\").register_models(models);\n module.exports = models;\n },\n \"custom/cave.plot.parallel_plot.parallel_reset.parallel_reset_tool\": function(require, module, exports) {\n \"use strict\";\n var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n })();\n Object.defineProperty(exports, \"__esModule\", { value: true });\n var action_tool_1 = require(\"models/tools/actions/action_tool\");\n var ParallelResetToolView = /** @class */ (function (_super) {\n __extends(ParallelResetToolView, _super);\n function ParallelResetToolView() {\n return _super !== null && _super.apply(this, arguments) || this;\n }\n ParallelResetToolView.prototype.doit = function () {\n this.plot_view.reset_range();\n };\n return ParallelResetToolView;\n }(action_tool_1.ActionToolView));\n exports.ParallelResetToolView = ParallelResetToolView;\n var ParallelResetTool = /** @class */ (function (_super) {\n __extends(ParallelResetTool, _super);\n function ParallelResetTool(attrs) {\n var _this = _super.call(this, attrs) || this;\n _this.tool_name = \"Reset Zoom\";\n _this.icon = \"bk-tool-icon-reset\";\n return _this;\n }\n ParallelResetTool.initClass = function () {\n this.prototype.type = \"ParallelResetTool\";\n this.prototype.default_view = ParallelResetToolView;\n };\n return ParallelResetTool;\n }(action_tool_1.ActionTool));\n exports.ParallelResetTool = ParallelResetTool;\n ParallelResetTool.initClass();\n\n },\n \"custom/cave.plot.parallel_plot.parallel_selection_tool.parallel_selection_tool\": function(require, module, exports) {\n \"use strict\";\n var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n })();\n Object.defineProperty(exports, \"__esModule\", { value: true });\n var p = require(\"core/properties\");\n var box_select_tool_1 = require(\"models/tools/gestures/box_select_tool\");\n var array_1 = require(\"core/util/array\");\n var dom_1 = require(\"core/dom\");\n function find_indices_in(array, _a) {\n var inf = _a[0], sup = _a[1];\n return array.reduce(function (prev, curr, index) {\n return (inf <= curr && curr <= sup) ? prev.concat(index) : prev;\n }, []);\n }\n function index_array(array, indices) {\n return indices.reduce(function (a, i) { return a.concat(array[i]); }, []);\n }\n function combineByKey(key, array) {\n var keys = Object.keys(array[0]);\n var combined = [];\n array.forEach(function (itm) {\n var idx = combined.map(function (item) { return item[key]; }).indexOf(itm[key]);\n if (idx >= 0) {\n keys.forEach(function (element) {\n if (element != key)\n combined[idx][element].push(itm[element]);\n });\n }\n else {\n var new_object_1 = {};\n keys.forEach(function (element) {\n if (element == key) {\n new_object_1[element] = itm[element];\n }\n else {\n new_object_1[element] = [itm[element]];\n }\n });\n combined.push(new_object_1);\n }\n });\n return combined;\n }\n var ParallelSelectionView = /** @class */ (function (_super) {\n __extends(ParallelSelectionView, _super);\n function ParallelSelectionView() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n _this.selection_mode = \"add\";\n _this.panning = false;\n return _this;\n }\n ParallelSelectionView.prototype.initialize = function () {\n var _this = this;\n _super.prototype.initialize.call(this);\n var frame = this.plot_view.frame;\n var _a = this.model.renderer_select, x_range_name_select = _a.x_range_name, y_range_name_select = _a.y_range_name;\n var _b = this.model.renderer_data, x_range_name_data = _b.x_range_name, y_range_name_data = _b.y_range_name;\n if (x_range_name_select == x_range_name_data && y_range_name_select == y_range_name_data) {\n this.xscale = frame.xscales[x_range_name_select];\n this.yscale = frame.yscales[y_range_name_select];\n }\n else\n throw new Error(\"selection and data does not share the same ranges\");\n //TODO test if parallel CDS is valid (xs for each line should be identical)\n this.glyph_select = this.model.renderer_select.glyph;\n this.glyph_data = this.model.renderer_data.glyph;\n this.cds_select = this.model.renderer_select.data_source;\n this.cds_data = this.model.renderer_data.data_source;\n var _c = [this.glyph_data.xs.field, this.glyph_data.ys.field], xskey = _c[0], yskey = _c[1];\n this.xdata = this.cds_data.get_array(xskey)[0];\n this.ydataT = array_1.transpose(this.cds_data.get_array(yskey));\n this.selection_indices = [];\n this.connect(this.plot_view.frame.x_ranges[this.model.renderer_select.x_range_name].change, function () { return _this._resize_boxes_on_zoom(); });\n this.connect(this.cds_select.change, function () { return _this._update_data_selection(); });\n };\n Object.defineProperty(ParallelSelectionView.prototype, \"_box_width\", {\n get: function () {\n return this.xscale.invert(this.model.box_width) - this.xscale.invert(0);\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(ParallelSelectionView.prototype, \"_cds_select_keys\", {\n get: function () {\n var glyph_select = this.glyph_select;\n var _a = [glyph_select.x.field, glyph_select.y.field], xkey = _a[0], ykey = _a[1];\n var _b = [glyph_select.width.field, glyph_select.height.field], wkey = _b[0], hkey = _b[1];\n return { xkey: xkey, ykey: ykey, wkey: wkey, hkey: hkey };\n },\n enumerable: true,\n configurable: true\n });\n ParallelSelectionView.prototype._emit_cds_changes = function (cds, redraw, clear, emit) {\n if (redraw === void 0) { redraw = true; }\n if (clear === void 0) { clear = true; }\n if (emit === void 0) { emit = true; }\n if (clear)\n cds.selection_manager.clear();\n if (redraw)\n cds.change.emit();\n if (emit) {\n cds.data = cds.data;\n cds.properties.data.change.emit();\n }\n };\n ParallelSelectionView.prototype._box_paramaters = function (index) {\n var _a = this._cds_select_keys, xkey = _a.xkey, ykey = _a.ykey, wkey = _a.wkey, hkey = _a.hkey;\n var x = this.cds_select.get_array(xkey)[index];\n var y = this.cds_select.get_array(ykey)[index];\n var w = this.cds_select.get_array(wkey)[index];\n var h = this.cds_select.get_array(hkey)[index];\n return { x: x, y: y, w: w, h: h };\n };\n ParallelSelectionView.prototype._hit_test_boxes = function (sx, sy) {\n var nboxes = this.cds_select.get_length();\n if (nboxes != 0 && nboxes != null) {\n var _a = [this.xscale.invert(sx), this.yscale.invert(sy)], xtest = _a[0], ytest = _a[1];\n for (var i = 0; i < nboxes; i++) {\n var _b = this._box_paramaters(i), x = _b.x, y = _b.y, w = _b.w, h = _b.h;\n if (xtest >= (x - w / 2) && xtest <= x + w / 2 &&\n ytest >= (y - h / 2) && ytest <= y + h / 2) {\n return i;\n }\n }\n }\n return null;\n };\n ParallelSelectionView.prototype._resize_boxes_on_zoom = function () {\n //resize selection boxes when zooming to keep a constant (pixel) size\n var cds = this.cds_select;\n var array_width = cds.get_array(this.glyph_select.width.field);\n var new_width = this._box_width;\n array_width.forEach(function (_, i) { return array_width[i] = new_width; });\n this._emit_cds_changes(cds, true, false, false);\n };\n ParallelSelectionView.prototype._drag_start = function (ev) {\n //Save y position of the drag start\n if (this.ind_active_box != null) {\n this._base_point = [this.xscale.invert(ev.sx), this.yscale.invert(ev.sy)];\n this._base_box_parameters = this._box_paramaters(this.ind_active_box);\n }\n };\n ParallelSelectionView.prototype._update_box_ypos = function (index_box, delta_y) {\n if (this._base_box_parameters != null) {\n var cds = this.cds_select;\n var ykey = this._cds_select_keys.ykey;\n var _a = this._base_box_parameters, current_y = _a.y, h = _a.h;\n var new_y = current_y + delta_y;\n new_y = new_y - Math.max(0, (new_y + h / 2) - 1) - Math.min(0, (new_y - h / 2));\n cds.get_array(ykey)[index_box] = new_y;\n this._emit_cds_changes(cds, true, false, false);\n this._update_selection_indices(index_box, [new_y - h / 2, new_y + h / 2]);\n }\n };\n ParallelSelectionView.prototype._drag = function (ev) {\n if (this.ind_active_box != null && this._base_point != null) {\n var delta_y = this.yscale.invert(ev.sy) - this._base_point[1];\n this._update_box_ypos(this.ind_active_box, delta_y);\n }\n };\n ParallelSelectionView.prototype._drag_stop = function (_ev) {\n this._base_point = null;\n this._base_box_parameters = null;\n };\n ParallelSelectionView.prototype._pan_start = function (ev) {\n this.panning = true;\n switch (this.selection_mode) {\n case \"add\": {\n _super.prototype._pan_start.call(this, ev);\n break;\n }\n case \"drag\": {\n this._drag_start(ev);\n break;\n }\n case \"resize\": {\n break;\n }\n }\n };\n ParallelSelectionView.prototype._pan = function (ev) {\n switch (this.selection_mode) {\n case \"add\": {\n _super.prototype._pan.call(this, ev);\n break;\n }\n case \"drag\": {\n this._drag(ev);\n break;\n }\n case \"resize\": {\n break;\n }\n }\n };\n ParallelSelectionView.prototype._pan_end = function (ev) {\n switch (this.selection_mode) {\n case \"add\": {\n _super.prototype._pan_end.call(this, ev);\n break;\n }\n case \"drag\": {\n this._drag_stop(ev);\n break;\n }\n case \"resize\": {\n break;\n }\n }\n this.panning = false;\n };\n ParallelSelectionView.prototype._move = function (ev) {\n //Switch mode\n if (this.panning) {\n return;\n }\n this.ind_active_box = this._hit_test_boxes(ev.sx, ev.sy);\n if (this.ind_active_box != null) {\n this.selection_mode = \"drag\";\n }\n else {\n this.selection_mode = \"add\";\n }\n };\n ParallelSelectionView.prototype._doubletap = function (_ev) {\n var _this = this;\n //delete box on double tap\n if (this.ind_active_box != null) {\n this.cds_select.columns().forEach(function (key) {\n _this.cds_select.get_array(key).splice(_this.ind_active_box, 1);\n });\n this._delete_selection_indices(this.ind_active_box);\n this._emit_cds_changes(this.cds_select);\n }\n };\n ParallelSelectionView.prototype._keyup = function (ev) {\n var _this = this;\n if (ev.keyCode == dom_1.Keys.Esc) {\n var nelems_1 = this.cds_select.get_length();\n if (nelems_1 != null) {\n this.cds_select.columns().forEach(function (key) {\n _this.cds_select.get_array(key).splice(0, nelems_1);\n });\n this.selection_indices.splice(0, nelems_1);\n this._emit_cds_changes(this.cds_select);\n }\n this.plot_view.request_render();\n }\n };\n ParallelSelectionView.prototype._update_data_selection = function () {\n var selection_indices = [];\n if (this.selection_indices.length > 0) {\n var combined_selections = combineByKey('data_idx', this.selection_indices);\n selection_indices = array_1.intersection.apply(void 0, [array_1.union.apply(void 0, combined_selections[0].indices)].concat(combined_selections.slice(1).map(function (elem) { return array_1.union.apply(void 0, elem.indices); })));\n }\n this.cds_data.selected.indices = selection_indices;\n this.cds_data.change.emit();\n };\n ParallelSelectionView.prototype._make_selection_indices = function (indices, _a) {\n var _this = this;\n var _b;\n var y0 = _a[0], y1 = _a[1];\n (_b = this.selection_indices).push.apply(_b, indices.map(function (index) {\n return {\n data_idx: index,\n indices: find_indices_in(_this.ydataT[index], [y0, y1]),\n };\n }));\n };\n ParallelSelectionView.prototype._update_selection_indices = function (index, _a) {\n var y0 = _a[0], y1 = _a[1];\n this.selection_indices[index].indices = find_indices_in(this.ydataT[this.selection_indices[index].data_idx], [y0, y1]);\n };\n ParallelSelectionView.prototype._delete_selection_indices = function (index) {\n this.selection_indices.splice(index, 1);\n };\n ParallelSelectionView.prototype._make_box_select = function (xs, _a) {\n var _this = this;\n var y0 = _a[0], y1 = _a[1];\n y0 = Math.max(0, y0);\n y1 = Math.min(1, y1);\n var y = (y0 + y1) / 2.;\n var w = this._box_width;\n var h = y1 - y0;\n var _b = this._cds_select_keys, xkey = _b.xkey, ykey = _b.ykey, wkey = _b.wkey, hkey = _b.hkey;\n xs.forEach(function (x) {\n if (xkey)\n _this.cds_select.get_array(xkey).push(x);\n if (ykey)\n _this.cds_select.get_array(ykey).push(y);\n if (wkey)\n _this.cds_select.get_array(wkey).push(w);\n if (hkey)\n _this.cds_select.get_array(hkey).push(h);\n });\n this._emit_cds_changes(this.cds_select);\n };\n ParallelSelectionView.prototype._do_select = function (_a, _b, _final, _append) {\n var sx0 = _a[0], sx1 = _a[1];\n var sy0 = _b[0], sy1 = _b[1];\n if (_final === void 0) { _final = true; }\n if (_append === void 0) { _append = true; }\n // Get selection bbox in the data space\n var _c = this.xscale.r_invert(sx0, sx1), x0 = _c[0], x1 = _c[1];\n var _d = this.yscale.r_invert(sy0, sy1), y0 = _d[0], y1 = _d[1];\n var x_indices = find_indices_in(this.xdata, [x0, x1]);\n var xs = index_array(this.xdata, x_indices);\n this._make_selection_indices(x_indices, [y0, y1]);\n this._make_box_select(xs, [y0, y1]);\n };\n return ParallelSelectionView;\n }(box_select_tool_1.BoxSelectToolView));\n exports.ParallelSelectionView = ParallelSelectionView;\n var ParallelSelectionTool = /** @class */ (function (_super) {\n __extends(ParallelSelectionTool, _super);\n function ParallelSelectionTool() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n _this.tool_name = \"Parallel Selection\";\n //override event_type property define in BoxSelectTool\n _this.event_type = [\"tap\", \"pan\", \"move\"];\n return _this;\n }\n ParallelSelectionTool.initClass = function () {\n this.prototype.type = \"ParallelSelectionTool\";\n this.prototype.default_view = ParallelSelectionView;\n this.define({\n renderer_select: [p.Any],\n renderer_data: [p.Any],\n box_width: [p.Number, 30],\n });\n };\n return ParallelSelectionTool;\n }(box_select_tool_1.BoxSelectTool));\n exports.ParallelSelectionTool = ParallelSelectionTool;\n ParallelSelectionTool.initClass();\n\n }\n }, \"custom/main\");\n ;\n });\n\n },\n function(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n \n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }if (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n var cell = $(document.getElementById(\"5122\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "
\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "(function(root) {\n", - " function embed_document(root) {\n", - " \n", - " var docs_json = {\"b4b772c4-59a0-4ce0-8e85-e1b915319642\":{\"roots\":{\"references\":[{\"attributes\":{\"children\":[{\"id\":\"5125\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"id\":\"5193\",\"type\":\"Column\"}]},\"id\":\"5194\",\"type\":\"Row\"},{\"attributes\":{\"line_color\":\"#d95f02\",\"x\":{\"field\":\"time\"},\"y\":{\"field\":\"mean\"}},\"id\":\"5170\",\"type\":\"Line\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#1f77b4\",\"x\":{\"field\":\"time\"},\"y\":{\"field\":\"mean\"}},\"id\":\"5160\",\"type\":\"Line\"},{\"attributes\":{\"active\":[0],\"callback\":{\"id\":\"5180\",\"type\":\"CustomJS\"},\"labels\":[\"all budgets\",\"budget_20000\"]},\"id\":\"5181\",\"type\":\"CheckboxButtonGroup\"},{\"attributes\":{\"data_source\":{\"id\":\"5123\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"5159\",\"type\":\"Line\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"5160\",\"type\":\"Line\"},\"selection_glyph\":null,\"view\":{\"id\":\"5157\",\"type\":\"CDSView\"}},\"id\":\"5161\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"children\":[{\"id\":\"5190\",\"type\":\"WidgetBox\"},{\"id\":\"5191\",\"type\":\"WidgetBox\"}]},\"id\":\"5192\",\"type\":\"Row\"},{\"attributes\":{\"line_alpha\":0.1,\"line_color\":\"#1f77b4\",\"x\":{\"field\":\"time\"},\"y\":{\"field\":\"mean\"}},\"id\":\"5171\",\"type\":\"Line\"},{\"attributes\":{\"children\":[{\"id\":\"5189\",\"type\":\"WidgetBox\"},{\"id\":\"5192\",\"type\":\"Row\"}]},\"id\":\"5193\",\"type\":\"Column\"},{\"attributes\":{\"data_source\":{\"id\":\"5123\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"5170\",\"type\":\"Line\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"5171\",\"type\":\"Line\"},\"selection_glyph\":null,\"view\":{\"id\":\"5168\",\"type\":\"CDSView\"},\"visible\":false},\"id\":\"5172\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"callback\":null,\"data\":{\"x\":{\"__ndarray__\":\"AAAAAAAA8D8AAAAAAADwPw==\",\"dtype\":\"float64\",\"shape\":[2]},\"y\":{\"__ndarray__\":\"OrTIdr4PVsA6tMh2vg9WwA==\",\"dtype\":\"float64\",\"shape\":[2]}},\"selected\":{\"id\":\"5204\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"5203\",\"type\":\"UnionRenderers\"}},\"id\":\"5162\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"args\":{\"checkbox\":{\"id\":\"5181\",\"type\":\"CheckboxButtonGroup\"},\"glyph_renderer0\":{\"id\":\"5161\",\"type\":\"GlyphRenderer\"},\"glyph_renderer1\":{\"id\":\"5165\",\"type\":\"GlyphRenderer\"},\"glyph_renderer2\":{\"id\":\"5172\",\"type\":\"GlyphRenderer\"},\"glyph_renderer3\":{\"id\":\"5176\",\"type\":\"GlyphRenderer\"}},\"code\":\"var labels = []; checkbox.active = labels;len_labels = 2;glyph_renderers = [[glyph_renderer0,glyph_renderer1],[glyph_renderer2,glyph_renderer3]];\\n for (i = 0; i < len_labels; i++) {\\n if (checkbox.active.includes(i)) {\\n // console.log('Setting to true: ' + i + '(' + glyph_renderers[i].length + ')')\\n for (j = 0; j < glyph_renderers[i].length; j++) {\\n glyph_renderers[i][j].visible = true;\\n // console.log('Setting to true: ' + i + ' : ' + j)\\n }\\n } else {\\n // console.log('Setting to false: ' + i + '(' + glyph_renderers[i].length + ')')\\n for (j = 0; j < glyph_renderers[i].length; j++) {\\n glyph_renderers[i][j].visible = false;\\n // console.log('Setting to false: ' + i + ' : ' + j)\\n }\\n }\\n }\\n \"},\"id\":\"5184\",\"type\":\"CustomJS\"},{\"attributes\":{\"data_source\":{\"id\":\"5162\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"5163\",\"type\":\"Patch\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"5164\",\"type\":\"Patch\"},\"selection_glyph\":null,\"view\":{\"id\":\"5166\",\"type\":\"CDSView\"}},\"id\":\"5165\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"callback\":null},\"id\":\"5129\",\"type\":\"DataRange1d\"},{\"attributes\":{\"fill_alpha\":0.2,\"fill_color\":\"#7570B3\",\"line_color\":\"#7570B3\",\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"5163\",\"type\":\"Patch\"},{\"attributes\":{},\"id\":\"5131\",\"type\":\"LogScale\"},{\"attributes\":{\"fill_alpha\":0.1,\"fill_color\":\"#1f77b4\",\"line_alpha\":0.1,\"line_color\":\"#1f77b4\",\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"5164\",\"type\":\"Patch\"},{\"attributes\":{},\"id\":\"5133\",\"type\":\"LinearScale\"},{\"attributes\":{\"children\":[{\"id\":\"5185\",\"type\":\"Button\"}],\"width\":50},\"id\":\"5191\",\"type\":\"WidgetBox\"},{\"attributes\":{\"axis_label\":\"time (sec)\",\"axis_label_text_font_size\":{\"value\":\"15pt\"},\"formatter\":{\"id\":\"5196\",\"type\":\"LogTickFormatter\"},\"major_label_orientation\":0.75,\"major_label_text_font_size\":{\"value\":\"12pt\"},\"ticker\":{\"id\":\"5136\",\"type\":\"LogTicker\"}},\"id\":\"5135\",\"type\":\"LogAxis\"},{\"attributes\":{},\"id\":\"5149\",\"type\":\"ResetTool\"},{\"attributes\":{},\"id\":\"5204\",\"type\":\"Selection\"},{\"attributes\":{\"callback\":{\"id\":\"5184\",\"type\":\"CustomJS\"},\"icon\":null,\"label\":\"None\"},\"id\":\"5185\",\"type\":\"Button\"},{\"attributes\":{\"num_minor_ticks\":10},\"id\":\"5136\",\"type\":\"LogTicker\"},{\"attributes\":{},\"id\":\"5205\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"args\":{\"glyph_renderer0\":{\"id\":\"5161\",\"type\":\"GlyphRenderer\"},\"glyph_renderer1\":{\"id\":\"5165\",\"type\":\"GlyphRenderer\"},\"glyph_renderer2\":{\"id\":\"5172\",\"type\":\"GlyphRenderer\"},\"glyph_renderer3\":{\"id\":\"5176\",\"type\":\"GlyphRenderer\"}},\"code\":\"len_labels = 2;glyph_renderers = [[glyph_renderer0,glyph_renderer1],[glyph_renderer2,glyph_renderer3]];\\n for (i = 0; i < len_labels; i++) {\\n if (cb_obj.active.includes(i)) {\\n // console.log('Setting to true: ' + i + '(' + glyph_renderers[i].length + ')')\\n for (j = 0; j < glyph_renderers[i].length; j++) {\\n glyph_renderers[i][j].visible = true;\\n // console.log('Setting to true: ' + i + ' : ' + j)\\n }\\n } else {\\n // console.log('Setting to false: ' + i + '(' + glyph_renderers[i].length + ')')\\n for (j = 0; j < glyph_renderers[i].length; j++) {\\n glyph_renderers[i][j].visible = false;\\n // console.log('Setting to false: ' + i + ' : ' + j)\\n }\\n }\\n }\\n \"},\"id\":\"5180\",\"type\":\"CustomJS\"},{\"attributes\":{\"active_drag\":\"auto\",\"active_inspect\":\"auto\",\"active_multi\":null,\"active_scroll\":\"auto\",\"active_tap\":\"auto\",\"tools\":[{\"id\":\"5145\",\"type\":\"SaveTool\"},{\"id\":\"5146\",\"type\":\"PanTool\"},{\"id\":\"5147\",\"type\":\"BoxZoomTool\"},{\"id\":\"5148\",\"type\":\"WheelZoomTool\"},{\"id\":\"5149\",\"type\":\"ResetTool\"},{\"id\":\"5178\",\"type\":\"HoverTool\"}]},\"id\":\"5150\",\"type\":\"Toolbar\"},{\"attributes\":{\"children\":[{\"id\":\"5181\",\"type\":\"CheckboxButtonGroup\"}],\"width\":100},\"id\":\"5189\",\"type\":\"WidgetBox\"},{\"attributes\":{},\"id\":\"5206\",\"type\":\"Selection\"},{\"attributes\":{\"overlay\":{\"id\":\"5200\",\"type\":\"BoxAnnotation\"}},\"id\":\"5147\",\"type\":\"BoxZoomTool\"},{\"attributes\":{\"children\":[{\"id\":\"5183\",\"type\":\"Button\"}],\"width\":50},\"id\":\"5190\",\"type\":\"WidgetBox\"},{\"attributes\":{\"click_policy\":\"hide\",\"items\":[{\"id\":\"5187\",\"type\":\"LegendItem\"},{\"id\":\"5188\",\"type\":\"LegendItem\"}],\"label_text_font_size\":{\"value\":\"8pt\"},\"location\":\"bottom_left\"},\"id\":\"5186\",\"type\":\"Legend\"},{\"attributes\":{\"label\":{\"value\":\"all budgets\"},\"renderers\":[{\"id\":\"5161\",\"type\":\"GlyphRenderer\"},{\"id\":\"5165\",\"type\":\"GlyphRenderer\"}]},\"id\":\"5187\",\"type\":\"LegendItem\"},{\"attributes\":{\"callback\":null,\"data\":{\"delay\":[\"inactive\",\"inactive\",\"inactive\",\"inactive\"],\"lower\":[-88.24600000000001,-86.743,-86.743,-88.24600000000001],\"mean\":[-88.24600000000001,-86.743,-86.743,-88.24600000000001],\"name\":[\"all budgets\",\"budget_20000\",\"budget_20000\",\"budget_20000\"],\"sequence_length\":[\"inactive\",\"inactive\",\"inactive\",\"inactive\"],\"time\":[1.0,2.1,21.9,21.9],\"upper\":[-88.24600000000001,-86.743,-86.743,-88.24600000000001]},\"selected\":{\"id\":\"5202\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"5201\",\"type\":\"UnionRenderers\"}},\"id\":\"5123\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"line_color\":\"#1b9e77\",\"x\":{\"field\":\"time\"},\"y\":{\"field\":\"mean\"}},\"id\":\"5159\",\"type\":\"Line\"},{\"attributes\":{\"callback\":null,\"data\":{\"x\":{\"__ndarray__\":\"zczMzMzMAEBmZmZmZuY1QGZmZmZm5jVAZmZmZmbmNUBmZmZmZuY1QM3MzMzMzABA\",\"dtype\":\"float64\",\"shape\":[6]},\"y\":{\"__ndarray__\":\"ZDvfT42vVcBkO99Pja9VwDq0yHa+D1bAOrTIdr4PVsBkO99Pja9VwGQ730+Nr1XA\",\"dtype\":\"float64\",\"shape\":[6]}},\"selected\":{\"id\":\"5206\",\"type\":\"Selection\"},\"selection_policy\":{\"id\":\"5205\",\"type\":\"UnionRenderers\"}},\"id\":\"5173\",\"type\":\"ColumnDataSource\"},{\"attributes\":{\"callback\":null,\"end\":21.9,\"start\":1.0},\"id\":\"5124\",\"type\":\"Range1d\"},{\"attributes\":{\"label\":{\"value\":\"budget_20000\"},\"renderers\":[{\"id\":\"5172\",\"type\":\"GlyphRenderer\"},{\"id\":\"5176\",\"type\":\"GlyphRenderer\"}]},\"id\":\"5188\",\"type\":\"LegendItem\"},{\"attributes\":{\"dimension\":1,\"ticker\":{\"id\":\"5141\",\"type\":\"BasicTicker\"}},\"id\":\"5144\",\"type\":\"Grid\"},{\"attributes\":{\"source\":{\"id\":\"5162\",\"type\":\"ColumnDataSource\"}},\"id\":\"5166\",\"type\":\"CDSView\"},{\"attributes\":{\"text\":\"Cost over time\",\"text_font_size\":{\"value\":\"15pt\"}},\"id\":\"5126\",\"type\":\"Title\"},{\"attributes\":{\"callback\":null,\"renderers\":[{\"id\":\"5161\",\"type\":\"GlyphRenderer\"},{\"id\":\"5165\",\"type\":\"GlyphRenderer\"},{\"id\":\"5172\",\"type\":\"GlyphRenderer\"},{\"id\":\"5176\",\"type\":\"GlyphRenderer\"}],\"tooltips\":[[\"estimated performance\",\"@mean\"],[\"at-time\",\"@time\"]]},\"id\":\"5178\",\"type\":\"HoverTool\"},{\"attributes\":{\"fill_alpha\":0.2,\"fill_color\":\"#7570B3\",\"line_color\":\"#7570B3\",\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"5174\",\"type\":\"Patch\"},{\"attributes\":{\"fill_alpha\":0.1,\"fill_color\":\"#1f77b4\",\"line_alpha\":0.1,\"line_color\":\"#1f77b4\",\"x\":{\"field\":\"x\"},\"y\":{\"field\":\"y\"}},\"id\":\"5175\",\"type\":\"Patch\"},{\"attributes\":{},\"id\":\"5203\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"background_fill_color\":{\"value\":null},\"below\":[{\"id\":\"5135\",\"type\":\"LogAxis\"}],\"border_fill_color\":{\"value\":null},\"center\":[{\"id\":\"5139\",\"type\":\"Grid\"},{\"id\":\"5144\",\"type\":\"Grid\"}],\"left\":[{\"id\":\"5140\",\"type\":\"LinearAxis\"}],\"plot_height\":500,\"plot_width\":700,\"renderers\":[{\"id\":\"5161\",\"type\":\"GlyphRenderer\"},{\"id\":\"5165\",\"type\":\"GlyphRenderer\"},{\"id\":\"5172\",\"type\":\"GlyphRenderer\"},{\"id\":\"5176\",\"type\":\"GlyphRenderer\"}],\"right\":[{\"id\":\"5186\",\"type\":\"Legend\"}],\"title\":{\"id\":\"5126\",\"type\":\"Title\"},\"toolbar\":{\"id\":\"5150\",\"type\":\"Toolbar\"},\"x_range\":{\"id\":\"5124\",\"type\":\"Range1d\"},\"x_scale\":{\"id\":\"5131\",\"type\":\"LogScale\"},\"y_range\":{\"id\":\"5129\",\"type\":\"DataRange1d\"},\"y_scale\":{\"id\":\"5133\",\"type\":\"LinearScale\"}},\"id\":\"5125\",\"subtype\":\"Figure\",\"type\":\"Plot\"},{\"attributes\":{\"ticker\":null},\"id\":\"5196\",\"type\":\"LogTickFormatter\"},{\"attributes\":{\"source\":{\"id\":\"5173\",\"type\":\"ColumnDataSource\"}},\"id\":\"5177\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"5198\",\"type\":\"BasicTickFormatter\"},{\"attributes\":{\"column_name\":\"name\",\"group\":\"all budgets\"},\"id\":\"5156\",\"type\":\"GroupFilter\"},{\"attributes\":{\"args\":{\"checkbox\":{\"id\":\"5181\",\"type\":\"CheckboxButtonGroup\"},\"glyph_renderer0\":{\"id\":\"5161\",\"type\":\"GlyphRenderer\"},\"glyph_renderer1\":{\"id\":\"5165\",\"type\":\"GlyphRenderer\"},\"glyph_renderer2\":{\"id\":\"5172\",\"type\":\"GlyphRenderer\"},\"glyph_renderer3\":{\"id\":\"5176\",\"type\":\"GlyphRenderer\"}},\"code\":\"var labels = [0, 1]; checkbox.active = labels;len_labels = 2;glyph_renderers = [[glyph_renderer0,glyph_renderer1],[glyph_renderer2,glyph_renderer3]];\\n for (i = 0; i < len_labels; i++) {\\n if (checkbox.active.includes(i)) {\\n // console.log('Setting to true: ' + i + '(' + glyph_renderers[i].length + ')')\\n for (j = 0; j < glyph_renderers[i].length; j++) {\\n glyph_renderers[i][j].visible = true;\\n // console.log('Setting to true: ' + i + ' : ' + j)\\n }\\n } else {\\n // console.log('Setting to false: ' + i + '(' + glyph_renderers[i].length + ')')\\n for (j = 0; j < glyph_renderers[i].length; j++) {\\n glyph_renderers[i][j].visible = false;\\n // console.log('Setting to false: ' + i + ' : ' + j)\\n }\\n }\\n }\\n \"},\"id\":\"5182\",\"type\":\"CustomJS\"},{\"attributes\":{\"data_source\":{\"id\":\"5173\",\"type\":\"ColumnDataSource\"},\"glyph\":{\"id\":\"5174\",\"type\":\"Patch\"},\"hover_glyph\":null,\"muted_glyph\":null,\"nonselection_glyph\":{\"id\":\"5175\",\"type\":\"Patch\"},\"selection_glyph\":null,\"view\":{\"id\":\"5177\",\"type\":\"CDSView\"},\"visible\":false},\"id\":\"5176\",\"type\":\"GlyphRenderer\"},{\"attributes\":{\"ticker\":{\"id\":\"5136\",\"type\":\"LogTicker\"}},\"id\":\"5139\",\"type\":\"Grid\"},{\"attributes\":{\"filters\":[{\"id\":\"5156\",\"type\":\"GroupFilter\"}],\"source\":{\"id\":\"5123\",\"type\":\"ColumnDataSource\"}},\"id\":\"5157\",\"type\":\"CDSView\"},{\"attributes\":{},\"id\":\"5146\",\"type\":\"PanTool\"},{\"attributes\":{\"bottom_units\":\"screen\",\"fill_alpha\":{\"value\":0.5},\"fill_color\":{\"value\":\"lightgrey\"},\"left_units\":\"screen\",\"level\":\"overlay\",\"line_alpha\":{\"value\":1.0},\"line_color\":{\"value\":\"black\"},\"line_dash\":[4,4],\"line_width\":{\"value\":2},\"render_mode\":\"css\",\"right_units\":\"screen\",\"top_units\":\"screen\"},\"id\":\"5200\",\"type\":\"BoxAnnotation\"},{\"attributes\":{},\"id\":\"5145\",\"type\":\"SaveTool\"},{\"attributes\":{},\"id\":\"5201\",\"type\":\"UnionRenderers\"},{\"attributes\":{\"callback\":{\"id\":\"5182\",\"type\":\"CustomJS\"},\"icon\":null,\"label\":\"All\"},\"id\":\"5183\",\"type\":\"Button\"},{\"attributes\":{},\"id\":\"5202\",\"type\":\"Selection\"},{\"attributes\":{\"column_name\":\"name\",\"group\":\"budget_20000\"},\"id\":\"5167\",\"type\":\"GroupFilter\"},{\"attributes\":{},\"id\":\"5148\",\"type\":\"WheelZoomTool\"},{\"attributes\":{},\"id\":\"5141\",\"type\":\"BasicTicker\"},{\"attributes\":{\"filters\":[{\"id\":\"5167\",\"type\":\"GroupFilter\"}],\"source\":{\"id\":\"5123\",\"type\":\"ColumnDataSource\"}},\"id\":\"5168\",\"type\":\"CDSView\"},{\"attributes\":{\"axis_label\":\"estimated cost\",\"axis_label_text_font_size\":{\"value\":\"15pt\"},\"formatter\":{\"id\":\"5198\",\"type\":\"BasicTickFormatter\"},\"major_label_text_font_size\":{\"value\":\"12pt\"},\"ticker\":{\"id\":\"5141\",\"type\":\"BasicTicker\"}},\"id\":\"5140\",\"type\":\"LinearAxis\"}],\"root_ids\":[\"5194\"]},\"title\":\"Bokeh Application\",\"version\":\"1.1.0\"}};\n", - " var render_items = [{\"docid\":\"b4b772c4-59a0-4ce0-8e85-e1b915319642\",\"roots\":{\"5194\":\"3f4d416e-e533-4b9a-9a9c-ba2f11322549\"}}];\n", - " root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n", - "\n", - " }\n", - " if (root.Bokeh !== undefined) {\n", - " embed_document(root);\n", - " } else {\n", - " var attempts = 0;\n", - " var timer = setInterval(function(root) {\n", - " if (root.Bokeh !== undefined) {\n", - " embed_document(root);\n", - " clearInterval(timer);\n", - " }\n", - " attempts++;\n", - " if (attempts > 100) {\n", - " console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n", - " clearInterval(timer);\n", - " }\n", - " }, 10, root)\n", - " }\n", - "})(window);" - ], - "application/vnd.bokehjs_exec.v0+json": "" - }, - "metadata": { - "application/vnd.bokehjs_exec.v0+json": { - "id": "5194" - } - }, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "cave.cost_over_time()" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - "
\n", - " \n", - " Loading BokehJS ...\n", - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/javascript": [ - "\n", - "(function(root) {\n", - " function now() {\n", - " return new Date();\n", - " }\n", - "\n", - " var force = true;\n", - "\n", - " if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n", - " root._bokeh_onload_callbacks = [];\n", - " root._bokeh_is_loading = undefined;\n", - " }\n", - "\n", - " var JS_MIME_TYPE = 'application/javascript';\n", - " var HTML_MIME_TYPE = 'text/html';\n", - " var EXEC_MIME_TYPE = 'application/vnd.bokehjs_exec.v0+json';\n", - " var CLASS_NAME = 'output_bokeh rendered_html';\n", - "\n", - " /**\n", - " * Render data to the DOM node\n", - " */\n", - " function render(props, node) {\n", - " var script = document.createElement(\"script\");\n", - " node.appendChild(script);\n", - " }\n", - "\n", - " /**\n", - " * Handle when an output is cleared or removed\n", - " */\n", - " function handleClearOutput(event, handle) {\n", - " var cell = handle.cell;\n", - "\n", - " var id = cell.output_area._bokeh_element_id;\n", - " var server_id = cell.output_area._bokeh_server_id;\n", - " // Clean up Bokeh references\n", - " if (id != null && id in Bokeh.index) {\n", - " Bokeh.index[id].model.document.clear();\n", - " delete Bokeh.index[id];\n", - " }\n", - "\n", - " if (server_id !== undefined) {\n", - " // Clean up Bokeh references\n", - " var cmd = \"from bokeh.io.state import curstate; print(curstate().uuid_to_server['\" + server_id + \"'].get_sessions()[0].document.roots[0]._id)\";\n", - " cell.notebook.kernel.execute(cmd, {\n", - " iopub: {\n", - " output: function(msg) {\n", - " var id = msg.content.text.trim();\n", - " if (id in Bokeh.index) {\n", - " Bokeh.index[id].model.document.clear();\n", - " delete Bokeh.index[id];\n", - " }\n", - " }\n", - " }\n", - " });\n", - " // Destroy server and session\n", - " var cmd = \"import bokeh.io.notebook as ion; ion.destroy_server('\" + server_id + \"')\";\n", - " cell.notebook.kernel.execute(cmd);\n", - " }\n", - " }\n", - "\n", - " /**\n", - " * Handle when a new output is added\n", - " */\n", - " function handleAddOutput(event, handle) {\n", - " var output_area = handle.output_area;\n", - " var output = handle.output;\n", - "\n", - " // limit handleAddOutput to display_data with EXEC_MIME_TYPE content only\n", - " if ((output.output_type != \"display_data\") || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n", - " return\n", - " }\n", - "\n", - " var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n", - "\n", - " if (output.metadata[EXEC_MIME_TYPE][\"id\"] !== undefined) {\n", - " toinsert[toinsert.length - 1].firstChild.textContent = output.data[JS_MIME_TYPE];\n", - " // store reference to embed id on output_area\n", - " output_area._bokeh_element_id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n", - " }\n", - " if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n", - " var bk_div = document.createElement(\"div\");\n", - " bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n", - " var script_attrs = bk_div.children[0].attributes;\n", - " for (var i = 0; i < script_attrs.length; i++) {\n", - " toinsert[toinsert.length - 1].firstChild.setAttribute(script_attrs[i].name, script_attrs[i].value);\n", - " }\n", - " // store reference to server id on output_area\n", - " output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n", - " }\n", - " }\n", - "\n", - " function register_renderer(events, OutputArea) {\n", - "\n", - " function append_mime(data, metadata, element) {\n", - " // create a DOM node to render to\n", - " var toinsert = this.create_output_subarea(\n", - " metadata,\n", - " CLASS_NAME,\n", - " EXEC_MIME_TYPE\n", - " );\n", - " this.keyboard_manager.register_events(toinsert);\n", - " // Render to node\n", - " var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n", - " render(props, toinsert[toinsert.length - 1]);\n", - " element.append(toinsert);\n", - " return toinsert\n", - " }\n", - "\n", - " /* Handle when an output is cleared or removed */\n", - " events.on('clear_output.CodeCell', handleClearOutput);\n", - " events.on('delete.Cell', handleClearOutput);\n", - "\n", - " /* Handle when a new output is added */\n", - " events.on('output_added.OutputArea', handleAddOutput);\n", - "\n", - " /**\n", - " * Register the mime type and append_mime function with output_area\n", - " */\n", - " OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n", - " /* Is output safe? */\n", - " safe: true,\n", - " /* Index of renderer in `output_area.display_order` */\n", - " index: 0\n", - " });\n", - " }\n", - "\n", - " // register the mime type if in Jupyter Notebook environment and previously unregistered\n", - " if (root.Jupyter !== undefined) {\n", - " var events = require('base/js/events');\n", - " var OutputArea = require('notebook/js/outputarea').OutputArea;\n", - "\n", - " if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n", - " register_renderer(events, OutputArea);\n", - " }\n", - " }\n", - "\n", - " \n", - " if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n", - " root._bokeh_timeout = Date.now() + 5000;\n", - " root._bokeh_failed_load = false;\n", - " }\n", - "\n", - " var NB_LOAD_WARNING = {'data': {'text/html':\n", - " \"
\\n\"+\n", - " \"

\\n\"+\n", - " \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n", - " \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n", - " \"

\\n\"+\n", - " \"
    \\n\"+\n", - " \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n", - " \"
  • use INLINE resources instead, as so:
  • \\n\"+\n", - " \"
\\n\"+\n", - " \"\\n\"+\n", - " \"from bokeh.resources import INLINE\\n\"+\n", - " \"output_notebook(resources=INLINE)\\n\"+\n", - " \"\\n\"+\n", - " \"
\"}};\n", - "\n", - " function display_loaded() {\n", - " var el = document.getElementById(\"1246\");\n", - " if (el != null) {\n", - " el.textContent = \"BokehJS is loading...\";\n", - " }\n", - " if (root.Bokeh !== undefined) {\n", - " if (el != null) {\n", - " el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n", - " }\n", - " } else if (Date.now() < root._bokeh_timeout) {\n", - " setTimeout(display_loaded, 100)\n", - " }\n", - " }\n", - "\n", - "\n", - " function run_callbacks() {\n", - " try {\n", - " root._bokeh_onload_callbacks.forEach(function(callback) {\n", - " if (callback != null)\n", - " callback();\n", - " });\n", - " } finally {\n", - " delete root._bokeh_onload_callbacks\n", - " }\n", - " console.debug(\"Bokeh: all callbacks have finished\");\n", - " }\n", - "\n", - " function load_libs(css_urls, js_urls, callback) {\n", - " if (css_urls == null) css_urls = [];\n", - " if (js_urls == null) js_urls = [];\n", - "\n", - " root._bokeh_onload_callbacks.push(callback);\n", - " if (root._bokeh_is_loading > 0) {\n", - " console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n", - " return null;\n", - " }\n", - " if (js_urls == null || js_urls.length === 0) {\n", - " run_callbacks();\n", - " return null;\n", - " }\n", - " console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n", - " root._bokeh_is_loading = css_urls.length + js_urls.length;\n", - "\n", - " function on_load() {\n", - " root._bokeh_is_loading--;\n", - " if (root._bokeh_is_loading === 0) {\n", - " console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n", - " run_callbacks()\n", - " }\n", - " }\n", - "\n", - " function on_error() {\n", - " console.error(\"failed to load \" + url);\n", - " }\n", - "\n", - " for (var i = 0; i < css_urls.length; i++) {\n", - " var url = css_urls[i];\n", - " const element = document.createElement(\"link\");\n", - " element.onload = on_load;\n", - " element.onerror = on_error;\n", - " element.rel = \"stylesheet\";\n", - " element.type = \"text/css\";\n", - " element.href = url;\n", - " console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n", - " document.body.appendChild(element);\n", - " }\n", - "\n", - " for (var i = 0; i < js_urls.length; i++) {\n", - " var url = js_urls[i];\n", - " var element = document.createElement('script');\n", - " element.onload = on_load;\n", - " element.onerror = on_error;\n", - " element.async = false;\n", - " element.src = url;\n", - " console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n", - " document.head.appendChild(element);\n", - " }\n", - " };var element = document.getElementById(\"1246\");\n", - " if (element == null) {\n", - " console.error(\"Bokeh: ERROR: autoload.js configured with elementid '1246' but no matching script tag was found. \")\n", - " return false;\n", - " }\n", - "\n", - " function inject_raw_css(css) {\n", - " const element = document.createElement(\"style\");\n", - " element.appendChild(document.createTextNode(css));\n", - " document.body.appendChild(element);\n", - " }\n", - "\n", - " var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.1.0.min.js\"];\n", - " var css_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.css\"];\n", - "\n", - " var inline_js = [\n", - " function(Bokeh) {\n", - " Bokeh.set_log_level(\"info\");\n", - " },\n", - " \n", - " function(Bokeh) {\n", - " (function(root, factory) {\n", - " // if(typeof exports === 'object' && typeof module === 'object')\n", - " // factory(require(\"Bokeh\"));\n", - " // else if(typeof define === 'function' && define.amd)\n", - " // define([\"Bokeh\"], factory);\n", - " // else if(typeof exports === 'object')\n", - " // factory(require(\"Bokeh\"));\n", - " // else\n", - " factory(root[\"Bokeh\"]);\n", - " })(this, function(Bokeh) {\n", - " var define;\n", - " return (function outer(modules, entry) {\n", - " if (Bokeh != null) {\n", - " return Bokeh.register_plugin(modules, {}, entry);\n", - " } else {\n", - " throw new Error(\"Cannot find Bokeh. You have to load it prior to loading plugins.\");\n", - " }\n", - " })\n", - " ({\n", - " \"custom/main\": function(require, module, exports) {\n", - " var models = {\n", - " \"ParallelResetTool\": require(\"custom/cave.plot.parallel_plot.parallel_reset.parallel_reset_tool\").ParallelResetTool,\n", - " \"ParallelSelectionTool\": require(\"custom/cave.plot.parallel_plot.parallel_selection_tool.parallel_selection_tool\").ParallelSelectionTool\n", - " };\n", - " require(\"base\").register_models(models);\n", - " module.exports = models;\n", - " },\n", - " \"custom/cave.plot.parallel_plot.parallel_reset.parallel_reset_tool\": function(require, module, exports) {\n", - " \"use strict\";\n", - " var __extends = (this && this.__extends) || (function () {\n", - " var extendStatics = function (d, b) {\n", - " extendStatics = Object.setPrototypeOf ||\n", - " ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n", - " function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n", - " return extendStatics(d, b);\n", - " };\n", - " return function (d, b) {\n", - " extendStatics(d, b);\n", - " function __() { this.constructor = d; }\n", - " d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n", - " };\n", - " })();\n", - " Object.defineProperty(exports, \"__esModule\", { value: true });\n", - " var action_tool_1 = require(\"models/tools/actions/action_tool\");\n", - " var ParallelResetToolView = /** @class */ (function (_super) {\n", - " __extends(ParallelResetToolView, _super);\n", - " function ParallelResetToolView() {\n", - " return _super !== null && _super.apply(this, arguments) || this;\n", - " }\n", - " ParallelResetToolView.prototype.doit = function () {\n", - " this.plot_view.reset_range();\n", - " };\n", - " return ParallelResetToolView;\n", - " }(action_tool_1.ActionToolView));\n", - " exports.ParallelResetToolView = ParallelResetToolView;\n", - " var ParallelResetTool = /** @class */ (function (_super) {\n", - " __extends(ParallelResetTool, _super);\n", - " function ParallelResetTool(attrs) {\n", - " var _this = _super.call(this, attrs) || this;\n", - " _this.tool_name = \"Reset Zoom\";\n", - " _this.icon = \"bk-tool-icon-reset\";\n", - " return _this;\n", - " }\n", - " ParallelResetTool.initClass = function () {\n", - " this.prototype.type = \"ParallelResetTool\";\n", - " this.prototype.default_view = ParallelResetToolView;\n", - " };\n", - " return ParallelResetTool;\n", - " }(action_tool_1.ActionTool));\n", - " exports.ParallelResetTool = ParallelResetTool;\n", - " ParallelResetTool.initClass();\n", - "\n", - " },\n", - " \"custom/cave.plot.parallel_plot.parallel_selection_tool.parallel_selection_tool\": function(require, module, exports) {\n", - " \"use strict\";\n", - " var __extends = (this && this.__extends) || (function () {\n", - " var extendStatics = function (d, b) {\n", - " extendStatics = Object.setPrototypeOf ||\n", - " ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n", - " function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n", - " return extendStatics(d, b);\n", - " };\n", - " return function (d, b) {\n", - " extendStatics(d, b);\n", - " function __() { this.constructor = d; }\n", - " d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n", - " };\n", - " })();\n", - " Object.defineProperty(exports, \"__esModule\", { value: true });\n", - " var p = require(\"core/properties\");\n", - " var box_select_tool_1 = require(\"models/tools/gestures/box_select_tool\");\n", - " var array_1 = require(\"core/util/array\");\n", - " var dom_1 = require(\"core/dom\");\n", - " function find_indices_in(array, _a) {\n", - " var inf = _a[0], sup = _a[1];\n", - " return array.reduce(function (prev, curr, index) {\n", - " return (inf <= curr && curr <= sup) ? prev.concat(index) : prev;\n", - " }, []);\n", - " }\n", - " function index_array(array, indices) {\n", - " return indices.reduce(function (a, i) { return a.concat(array[i]); }, []);\n", - " }\n", - " function combineByKey(key, array) {\n", - " var keys = Object.keys(array[0]);\n", - " var combined = [];\n", - " array.forEach(function (itm) {\n", - " var idx = combined.map(function (item) { return item[key]; }).indexOf(itm[key]);\n", - " if (idx >= 0) {\n", - " keys.forEach(function (element) {\n", - " if (element != key)\n", - " combined[idx][element].push(itm[element]);\n", - " });\n", - " }\n", - " else {\n", - " var new_object_1 = {};\n", - " keys.forEach(function (element) {\n", - " if (element == key) {\n", - " new_object_1[element] = itm[element];\n", - " }\n", - " else {\n", - " new_object_1[element] = [itm[element]];\n", - " }\n", - " });\n", - " combined.push(new_object_1);\n", - " }\n", - " });\n", - " return combined;\n", - " }\n", - " var ParallelSelectionView = /** @class */ (function (_super) {\n", - " __extends(ParallelSelectionView, _super);\n", - " function ParallelSelectionView() {\n", - " var _this = _super !== null && _super.apply(this, arguments) || this;\n", - " _this.selection_mode = \"add\";\n", - " _this.panning = false;\n", - " return _this;\n", - " }\n", - " ParallelSelectionView.prototype.initialize = function () {\n", - " var _this = this;\n", - " _super.prototype.initialize.call(this);\n", - " var frame = this.plot_view.frame;\n", - " var _a = this.model.renderer_select, x_range_name_select = _a.x_range_name, y_range_name_select = _a.y_range_name;\n", - " var _b = this.model.renderer_data, x_range_name_data = _b.x_range_name, y_range_name_data = _b.y_range_name;\n", - " if (x_range_name_select == x_range_name_data && y_range_name_select == y_range_name_data) {\n", - " this.xscale = frame.xscales[x_range_name_select];\n", - " this.yscale = frame.yscales[y_range_name_select];\n", - " }\n", - " else\n", - " throw new Error(\"selection and data does not share the same ranges\");\n", - " //TODO test if parallel CDS is valid (xs for each line should be identical)\n", - " this.glyph_select = this.model.renderer_select.glyph;\n", - " this.glyph_data = this.model.renderer_data.glyph;\n", - " this.cds_select = this.model.renderer_select.data_source;\n", - " this.cds_data = this.model.renderer_data.data_source;\n", - " var _c = [this.glyph_data.xs.field, this.glyph_data.ys.field], xskey = _c[0], yskey = _c[1];\n", - " this.xdata = this.cds_data.get_array(xskey)[0];\n", - " this.ydataT = array_1.transpose(this.cds_data.get_array(yskey));\n", - " this.selection_indices = [];\n", - " this.connect(this.plot_view.frame.x_ranges[this.model.renderer_select.x_range_name].change, function () { return _this._resize_boxes_on_zoom(); });\n", - " this.connect(this.cds_select.change, function () { return _this._update_data_selection(); });\n", - " };\n", - " Object.defineProperty(ParallelSelectionView.prototype, \"_box_width\", {\n", - " get: function () {\n", - " return this.xscale.invert(this.model.box_width) - this.xscale.invert(0);\n", - " },\n", - " enumerable: true,\n", - " configurable: true\n", - " });\n", - " Object.defineProperty(ParallelSelectionView.prototype, \"_cds_select_keys\", {\n", - " get: function () {\n", - " var glyph_select = this.glyph_select;\n", - " var _a = [glyph_select.x.field, glyph_select.y.field], xkey = _a[0], ykey = _a[1];\n", - " var _b = [glyph_select.width.field, glyph_select.height.field], wkey = _b[0], hkey = _b[1];\n", - " return { xkey: xkey, ykey: ykey, wkey: wkey, hkey: hkey };\n", - " },\n", - " enumerable: true,\n", - " configurable: true\n", - " });\n", - " ParallelSelectionView.prototype._emit_cds_changes = function (cds, redraw, clear, emit) {\n", - " if (redraw === void 0) { redraw = true; }\n", - " if (clear === void 0) { clear = true; }\n", - " if (emit === void 0) { emit = true; }\n", - " if (clear)\n", - " cds.selection_manager.clear();\n", - " if (redraw)\n", - " cds.change.emit();\n", - " if (emit) {\n", - " cds.data = cds.data;\n", - " cds.properties.data.change.emit();\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._box_paramaters = function (index) {\n", - " var _a = this._cds_select_keys, xkey = _a.xkey, ykey = _a.ykey, wkey = _a.wkey, hkey = _a.hkey;\n", - " var x = this.cds_select.get_array(xkey)[index];\n", - " var y = this.cds_select.get_array(ykey)[index];\n", - " var w = this.cds_select.get_array(wkey)[index];\n", - " var h = this.cds_select.get_array(hkey)[index];\n", - " return { x: x, y: y, w: w, h: h };\n", - " };\n", - " ParallelSelectionView.prototype._hit_test_boxes = function (sx, sy) {\n", - " var nboxes = this.cds_select.get_length();\n", - " if (nboxes != 0 && nboxes != null) {\n", - " var _a = [this.xscale.invert(sx), this.yscale.invert(sy)], xtest = _a[0], ytest = _a[1];\n", - " for (var i = 0; i < nboxes; i++) {\n", - " var _b = this._box_paramaters(i), x = _b.x, y = _b.y, w = _b.w, h = _b.h;\n", - " if (xtest >= (x - w / 2) && xtest <= x + w / 2 &&\n", - " ytest >= (y - h / 2) && ytest <= y + h / 2) {\n", - " return i;\n", - " }\n", - " }\n", - " }\n", - " return null;\n", - " };\n", - " ParallelSelectionView.prototype._resize_boxes_on_zoom = function () {\n", - " //resize selection boxes when zooming to keep a constant (pixel) size\n", - " var cds = this.cds_select;\n", - " var array_width = cds.get_array(this.glyph_select.width.field);\n", - " var new_width = this._box_width;\n", - " array_width.forEach(function (_, i) { return array_width[i] = new_width; });\n", - " this._emit_cds_changes(cds, true, false, false);\n", - " };\n", - " ParallelSelectionView.prototype._drag_start = function (ev) {\n", - " //Save y position of the drag start\n", - " if (this.ind_active_box != null) {\n", - " this._base_point = [this.xscale.invert(ev.sx), this.yscale.invert(ev.sy)];\n", - " this._base_box_parameters = this._box_paramaters(this.ind_active_box);\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._update_box_ypos = function (index_box, delta_y) {\n", - " if (this._base_box_parameters != null) {\n", - " var cds = this.cds_select;\n", - " var ykey = this._cds_select_keys.ykey;\n", - " var _a = this._base_box_parameters, current_y = _a.y, h = _a.h;\n", - " var new_y = current_y + delta_y;\n", - " new_y = new_y - Math.max(0, (new_y + h / 2) - 1) - Math.min(0, (new_y - h / 2));\n", - " cds.get_array(ykey)[index_box] = new_y;\n", - " this._emit_cds_changes(cds, true, false, false);\n", - " this._update_selection_indices(index_box, [new_y - h / 2, new_y + h / 2]);\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._drag = function (ev) {\n", - " if (this.ind_active_box != null && this._base_point != null) {\n", - " var delta_y = this.yscale.invert(ev.sy) - this._base_point[1];\n", - " this._update_box_ypos(this.ind_active_box, delta_y);\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._drag_stop = function (_ev) {\n", - " this._base_point = null;\n", - " this._base_box_parameters = null;\n", - " };\n", - " ParallelSelectionView.prototype._pan_start = function (ev) {\n", - " this.panning = true;\n", - " switch (this.selection_mode) {\n", - " case \"add\": {\n", - " _super.prototype._pan_start.call(this, ev);\n", - " break;\n", - " }\n", - " case \"drag\": {\n", - " this._drag_start(ev);\n", - " break;\n", - " }\n", - " case \"resize\": {\n", - " break;\n", - " }\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._pan = function (ev) {\n", - " switch (this.selection_mode) {\n", - " case \"add\": {\n", - " _super.prototype._pan.call(this, ev);\n", - " break;\n", - " }\n", - " case \"drag\": {\n", - " this._drag(ev);\n", - " break;\n", - " }\n", - " case \"resize\": {\n", - " break;\n", - " }\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._pan_end = function (ev) {\n", - " switch (this.selection_mode) {\n", - " case \"add\": {\n", - " _super.prototype._pan_end.call(this, ev);\n", - " break;\n", - " }\n", - " case \"drag\": {\n", - " this._drag_stop(ev);\n", - " break;\n", - " }\n", - " case \"resize\": {\n", - " break;\n", - " }\n", - " }\n", - " this.panning = false;\n", - " };\n", - " ParallelSelectionView.prototype._move = function (ev) {\n", - " //Switch mode\n", - " if (this.panning) {\n", - " return;\n", - " }\n", - " this.ind_active_box = this._hit_test_boxes(ev.sx, ev.sy);\n", - " if (this.ind_active_box != null) {\n", - " this.selection_mode = \"drag\";\n", - " }\n", - " else {\n", - " this.selection_mode = \"add\";\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._doubletap = function (_ev) {\n", - " var _this = this;\n", - " //delete box on double tap\n", - " if (this.ind_active_box != null) {\n", - " this.cds_select.columns().forEach(function (key) {\n", - " _this.cds_select.get_array(key).splice(_this.ind_active_box, 1);\n", - " });\n", - " this._delete_selection_indices(this.ind_active_box);\n", - " this._emit_cds_changes(this.cds_select);\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._keyup = function (ev) {\n", - " var _this = this;\n", - " if (ev.keyCode == dom_1.Keys.Esc) {\n", - " var nelems_1 = this.cds_select.get_length();\n", - " if (nelems_1 != null) {\n", - " this.cds_select.columns().forEach(function (key) {\n", - " _this.cds_select.get_array(key).splice(0, nelems_1);\n", - " });\n", - " this.selection_indices.splice(0, nelems_1);\n", - " this._emit_cds_changes(this.cds_select);\n", - " }\n", - " this.plot_view.request_render();\n", - " }\n", - " };\n", - " ParallelSelectionView.prototype._update_data_selection = function () {\n", - " var selection_indices = [];\n", - " if (this.selection_indices.length > 0) {\n", - " var combined_selections = combineByKey('data_idx', this.selection_indices);\n", - " selection_indices = array_1.intersection.apply(void 0, [array_1.union.apply(void 0, combined_selections[0].indices)].concat(combined_selections.slice(1).map(function (elem) { return array_1.union.apply(void 0, elem.indices); })));\n", - " }\n", - " this.cds_data.selected.indices = selection_indices;\n", - " this.cds_data.change.emit();\n", - " };\n", - " ParallelSelectionView.prototype._make_selection_indices = function (indices, _a) {\n", - " var _this = this;\n", - " var _b;\n", - " var y0 = _a[0], y1 = _a[1];\n", - " (_b = this.selection_indices).push.apply(_b, indices.map(function (index) {\n", - " return {\n", - " data_idx: index,\n", - " indices: find_indices_in(_this.ydataT[index], [y0, y1]),\n", - " };\n", - " }));\n", - " };\n", - " ParallelSelectionView.prototype._update_selection_indices = function (index, _a) {\n", - " var y0 = _a[0], y1 = _a[1];\n", - " this.selection_indices[index].indices = find_indices_in(this.ydataT[this.selection_indices[index].data_idx], [y0, y1]);\n", - " };\n", - " ParallelSelectionView.prototype._delete_selection_indices = function (index) {\n", - " this.selection_indices.splice(index, 1);\n", - " };\n", - " ParallelSelectionView.prototype._make_box_select = function (xs, _a) {\n", - " var _this = this;\n", - " var y0 = _a[0], y1 = _a[1];\n", - " y0 = Math.max(0, y0);\n", - " y1 = Math.min(1, y1);\n", - " var y = (y0 + y1) / 2.;\n", - " var w = this._box_width;\n", - " var h = y1 - y0;\n", - " var _b = this._cds_select_keys, xkey = _b.xkey, ykey = _b.ykey, wkey = _b.wkey, hkey = _b.hkey;\n", - " xs.forEach(function (x) {\n", - " if (xkey)\n", - " _this.cds_select.get_array(xkey).push(x);\n", - " if (ykey)\n", - " _this.cds_select.get_array(ykey).push(y);\n", - " if (wkey)\n", - " _this.cds_select.get_array(wkey).push(w);\n", - " if (hkey)\n", - " _this.cds_select.get_array(hkey).push(h);\n", - " });\n", - " this._emit_cds_changes(this.cds_select);\n", - " };\n", - " ParallelSelectionView.prototype._do_select = function (_a, _b, _final, _append) {\n", - " var sx0 = _a[0], sx1 = _a[1];\n", - " var sy0 = _b[0], sy1 = _b[1];\n", - " if (_final === void 0) { _final = true; }\n", - " if (_append === void 0) { _append = true; }\n", - " // Get selection bbox in the data space\n", - " var _c = this.xscale.r_invert(sx0, sx1), x0 = _c[0], x1 = _c[1];\n", - " var _d = this.yscale.r_invert(sy0, sy1), y0 = _d[0], y1 = _d[1];\n", - " var x_indices = find_indices_in(this.xdata, [x0, x1]);\n", - " var xs = index_array(this.xdata, x_indices);\n", - " this._make_selection_indices(x_indices, [y0, y1]);\n", - " this._make_box_select(xs, [y0, y1]);\n", - " };\n", - " return ParallelSelectionView;\n", - " }(box_select_tool_1.BoxSelectToolView));\n", - " exports.ParallelSelectionView = ParallelSelectionView;\n", - " var ParallelSelectionTool = /** @class */ (function (_super) {\n", - " __extends(ParallelSelectionTool, _super);\n", - " function ParallelSelectionTool() {\n", - " var _this = _super !== null && _super.apply(this, arguments) || this;\n", - " _this.tool_name = \"Parallel Selection\";\n", - " //override event_type property define in BoxSelectTool\n", - " _this.event_type = [\"tap\", \"pan\", \"move\"];\n", - " return _this;\n", - " }\n", - " ParallelSelectionTool.initClass = function () {\n", - " this.prototype.type = \"ParallelSelectionTool\";\n", - " this.prototype.default_view = ParallelSelectionView;\n", - " this.define({\n", - " renderer_select: [p.Any],\n", - " renderer_data: [p.Any],\n", - " box_width: [p.Number, 30],\n", - " });\n", - " };\n", - " return ParallelSelectionTool;\n", - " }(box_select_tool_1.BoxSelectTool));\n", - " exports.ParallelSelectionTool = ParallelSelectionTool;\n", - " ParallelSelectionTool.initClass();\n", - "\n", - " }\n", - " }, \"custom/main\");\n", - " ;\n", - " });\n", - "\n", - " },\n", - " function(Bokeh) {} // ensure no trailing comma for IE\n", - " ];\n", - "\n", - " function run_inline_js() {\n", - " \n", - " if ((root.Bokeh !== undefined) || (force === true)) {\n", - " for (var i = 0; i < inline_js.length; i++) {\n", - " inline_js[i].call(root, root.Bokeh);\n", - " }if (force === true) {\n", - " display_loaded();\n", - " }} else if (Date.now() < root._bokeh_timeout) {\n", - " setTimeout(run_inline_js, 100);\n", - " } else if (!root._bokeh_failed_load) {\n", - " console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n", - " root._bokeh_failed_load = true;\n", - " } else if (force !== true) {\n", - " var cell = $(document.getElementById(\"1246\")).parents('.cell').data().cell;\n", - " cell.output_area.append_execute_result(NB_LOAD_WARNING)\n", - " }\n", - "\n", - " }\n", - "\n", - " if (root._bokeh_is_loading === 0) {\n", - " console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n", - " run_inline_js();\n", - " } else {\n", - " load_libs(css_urls, js_urls, function() {\n", - " console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n", - " run_inline_js();\n", - " });\n", - " }\n", - "}(window));" - ], - "application/vnd.bokehjs_load.v0+json": "\n(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n \n\n \n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n var NB_LOAD_WARNING = {'data': {'text/html':\n \"
\\n\"+\n \"

\\n\"+\n \"BokehJS does not appear to have successfully loaded. If loading BokehJS from CDN, this \\n\"+\n \"may be due to a slow or bad network connection. Possible fixes:\\n\"+\n \"

\\n\"+\n \"
    \\n\"+\n \"
  • re-rerun `output_notebook()` to attempt to load from CDN again, or
  • \\n\"+\n \"
  • use INLINE resources instead, as so:
  • \\n\"+\n \"
\\n\"+\n \"\\n\"+\n \"from bokeh.resources import INLINE\\n\"+\n \"output_notebook(resources=INLINE)\\n\"+\n \"\\n\"+\n \"
\"}};\n\n function display_loaded() {\n var el = document.getElementById(\"1246\");\n if (el != null) {\n el.textContent = \"BokehJS is loading...\";\n }\n if (root.Bokeh !== undefined) {\n if (el != null) {\n el.textContent = \"BokehJS \" + root.Bokeh.version + \" successfully loaded.\";\n }\n } else if (Date.now() < root._bokeh_timeout) {\n setTimeout(display_loaded, 100)\n }\n }\n\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n };var element = document.getElementById(\"1246\");\n if (element == null) {\n console.error(\"Bokeh: ERROR: autoload.js configured with elementid '1246' but no matching script tag was found. \")\n return false;\n }\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.js\", \"https://cdn.pydata.org/bokeh/release/bokeh-gl-1.1.0.min.js\"];\n var css_urls = [\"https://cdn.pydata.org/bokeh/release/bokeh-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-widgets-1.1.0.min.css\", \"https://cdn.pydata.org/bokeh/release/bokeh-tables-1.1.0.min.css\"];\n\n var inline_js = [\n function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n \n function(Bokeh) {\n (function(root, factory) {\n // if(typeof exports === 'object' && typeof module === 'object')\n // factory(require(\"Bokeh\"));\n // else if(typeof define === 'function' && define.amd)\n // define([\"Bokeh\"], factory);\n // else if(typeof exports === 'object')\n // factory(require(\"Bokeh\"));\n // else\n factory(root[\"Bokeh\"]);\n })(this, function(Bokeh) {\n var define;\n return (function outer(modules, entry) {\n if (Bokeh != null) {\n return Bokeh.register_plugin(modules, {}, entry);\n } else {\n throw new Error(\"Cannot find Bokeh. You have to load it prior to loading plugins.\");\n }\n })\n ({\n \"custom/main\": function(require, module, exports) {\n var models = {\n \"ParallelResetTool\": require(\"custom/cave.plot.parallel_plot.parallel_reset.parallel_reset_tool\").ParallelResetTool,\n \"ParallelSelectionTool\": require(\"custom/cave.plot.parallel_plot.parallel_selection_tool.parallel_selection_tool\").ParallelSelectionTool\n };\n require(\"base\").register_models(models);\n module.exports = models;\n },\n \"custom/cave.plot.parallel_plot.parallel_reset.parallel_reset_tool\": function(require, module, exports) {\n \"use strict\";\n var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n })();\n Object.defineProperty(exports, \"__esModule\", { value: true });\n var action_tool_1 = require(\"models/tools/actions/action_tool\");\n var ParallelResetToolView = /** @class */ (function (_super) {\n __extends(ParallelResetToolView, _super);\n function ParallelResetToolView() {\n return _super !== null && _super.apply(this, arguments) || this;\n }\n ParallelResetToolView.prototype.doit = function () {\n this.plot_view.reset_range();\n };\n return ParallelResetToolView;\n }(action_tool_1.ActionToolView));\n exports.ParallelResetToolView = ParallelResetToolView;\n var ParallelResetTool = /** @class */ (function (_super) {\n __extends(ParallelResetTool, _super);\n function ParallelResetTool(attrs) {\n var _this = _super.call(this, attrs) || this;\n _this.tool_name = \"Reset Zoom\";\n _this.icon = \"bk-tool-icon-reset\";\n return _this;\n }\n ParallelResetTool.initClass = function () {\n this.prototype.type = \"ParallelResetTool\";\n this.prototype.default_view = ParallelResetToolView;\n };\n return ParallelResetTool;\n }(action_tool_1.ActionTool));\n exports.ParallelResetTool = ParallelResetTool;\n ParallelResetTool.initClass();\n\n },\n \"custom/cave.plot.parallel_plot.parallel_selection_tool.parallel_selection_tool\": function(require, module, exports) {\n \"use strict\";\n var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n })();\n Object.defineProperty(exports, \"__esModule\", { value: true });\n var p = require(\"core/properties\");\n var box_select_tool_1 = require(\"models/tools/gestures/box_select_tool\");\n var array_1 = require(\"core/util/array\");\n var dom_1 = require(\"core/dom\");\n function find_indices_in(array, _a) {\n var inf = _a[0], sup = _a[1];\n return array.reduce(function (prev, curr, index) {\n return (inf <= curr && curr <= sup) ? prev.concat(index) : prev;\n }, []);\n }\n function index_array(array, indices) {\n return indices.reduce(function (a, i) { return a.concat(array[i]); }, []);\n }\n function combineByKey(key, array) {\n var keys = Object.keys(array[0]);\n var combined = [];\n array.forEach(function (itm) {\n var idx = combined.map(function (item) { return item[key]; }).indexOf(itm[key]);\n if (idx >= 0) {\n keys.forEach(function (element) {\n if (element != key)\n combined[idx][element].push(itm[element]);\n });\n }\n else {\n var new_object_1 = {};\n keys.forEach(function (element) {\n if (element == key) {\n new_object_1[element] = itm[element];\n }\n else {\n new_object_1[element] = [itm[element]];\n }\n });\n combined.push(new_object_1);\n }\n });\n return combined;\n }\n var ParallelSelectionView = /** @class */ (function (_super) {\n __extends(ParallelSelectionView, _super);\n function ParallelSelectionView() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n _this.selection_mode = \"add\";\n _this.panning = false;\n return _this;\n }\n ParallelSelectionView.prototype.initialize = function () {\n var _this = this;\n _super.prototype.initialize.call(this);\n var frame = this.plot_view.frame;\n var _a = this.model.renderer_select, x_range_name_select = _a.x_range_name, y_range_name_select = _a.y_range_name;\n var _b = this.model.renderer_data, x_range_name_data = _b.x_range_name, y_range_name_data = _b.y_range_name;\n if (x_range_name_select == x_range_name_data && y_range_name_select == y_range_name_data) {\n this.xscale = frame.xscales[x_range_name_select];\n this.yscale = frame.yscales[y_range_name_select];\n }\n else\n throw new Error(\"selection and data does not share the same ranges\");\n //TODO test if parallel CDS is valid (xs for each line should be identical)\n this.glyph_select = this.model.renderer_select.glyph;\n this.glyph_data = this.model.renderer_data.glyph;\n this.cds_select = this.model.renderer_select.data_source;\n this.cds_data = this.model.renderer_data.data_source;\n var _c = [this.glyph_data.xs.field, this.glyph_data.ys.field], xskey = _c[0], yskey = _c[1];\n this.xdata = this.cds_data.get_array(xskey)[0];\n this.ydataT = array_1.transpose(this.cds_data.get_array(yskey));\n this.selection_indices = [];\n this.connect(this.plot_view.frame.x_ranges[this.model.renderer_select.x_range_name].change, function () { return _this._resize_boxes_on_zoom(); });\n this.connect(this.cds_select.change, function () { return _this._update_data_selection(); });\n };\n Object.defineProperty(ParallelSelectionView.prototype, \"_box_width\", {\n get: function () {\n return this.xscale.invert(this.model.box_width) - this.xscale.invert(0);\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(ParallelSelectionView.prototype, \"_cds_select_keys\", {\n get: function () {\n var glyph_select = this.glyph_select;\n var _a = [glyph_select.x.field, glyph_select.y.field], xkey = _a[0], ykey = _a[1];\n var _b = [glyph_select.width.field, glyph_select.height.field], wkey = _b[0], hkey = _b[1];\n return { xkey: xkey, ykey: ykey, wkey: wkey, hkey: hkey };\n },\n enumerable: true,\n configurable: true\n });\n ParallelSelectionView.prototype._emit_cds_changes = function (cds, redraw, clear, emit) {\n if (redraw === void 0) { redraw = true; }\n if (clear === void 0) { clear = true; }\n if (emit === void 0) { emit = true; }\n if (clear)\n cds.selection_manager.clear();\n if (redraw)\n cds.change.emit();\n if (emit) {\n cds.data = cds.data;\n cds.properties.data.change.emit();\n }\n };\n ParallelSelectionView.prototype._box_paramaters = function (index) {\n var _a = this._cds_select_keys, xkey = _a.xkey, ykey = _a.ykey, wkey = _a.wkey, hkey = _a.hkey;\n var x = this.cds_select.get_array(xkey)[index];\n var y = this.cds_select.get_array(ykey)[index];\n var w = this.cds_select.get_array(wkey)[index];\n var h = this.cds_select.get_array(hkey)[index];\n return { x: x, y: y, w: w, h: h };\n };\n ParallelSelectionView.prototype._hit_test_boxes = function (sx, sy) {\n var nboxes = this.cds_select.get_length();\n if (nboxes != 0 && nboxes != null) {\n var _a = [this.xscale.invert(sx), this.yscale.invert(sy)], xtest = _a[0], ytest = _a[1];\n for (var i = 0; i < nboxes; i++) {\n var _b = this._box_paramaters(i), x = _b.x, y = _b.y, w = _b.w, h = _b.h;\n if (xtest >= (x - w / 2) && xtest <= x + w / 2 &&\n ytest >= (y - h / 2) && ytest <= y + h / 2) {\n return i;\n }\n }\n }\n return null;\n };\n ParallelSelectionView.prototype._resize_boxes_on_zoom = function () {\n //resize selection boxes when zooming to keep a constant (pixel) size\n var cds = this.cds_select;\n var array_width = cds.get_array(this.glyph_select.width.field);\n var new_width = this._box_width;\n array_width.forEach(function (_, i) { return array_width[i] = new_width; });\n this._emit_cds_changes(cds, true, false, false);\n };\n ParallelSelectionView.prototype._drag_start = function (ev) {\n //Save y position of the drag start\n if (this.ind_active_box != null) {\n this._base_point = [this.xscale.invert(ev.sx), this.yscale.invert(ev.sy)];\n this._base_box_parameters = this._box_paramaters(this.ind_active_box);\n }\n };\n ParallelSelectionView.prototype._update_box_ypos = function (index_box, delta_y) {\n if (this._base_box_parameters != null) {\n var cds = this.cds_select;\n var ykey = this._cds_select_keys.ykey;\n var _a = this._base_box_parameters, current_y = _a.y, h = _a.h;\n var new_y = current_y + delta_y;\n new_y = new_y - Math.max(0, (new_y + h / 2) - 1) - Math.min(0, (new_y - h / 2));\n cds.get_array(ykey)[index_box] = new_y;\n this._emit_cds_changes(cds, true, false, false);\n this._update_selection_indices(index_box, [new_y - h / 2, new_y + h / 2]);\n }\n };\n ParallelSelectionView.prototype._drag = function (ev) {\n if (this.ind_active_box != null && this._base_point != null) {\n var delta_y = this.yscale.invert(ev.sy) - this._base_point[1];\n this._update_box_ypos(this.ind_active_box, delta_y);\n }\n };\n ParallelSelectionView.prototype._drag_stop = function (_ev) {\n this._base_point = null;\n this._base_box_parameters = null;\n };\n ParallelSelectionView.prototype._pan_start = function (ev) {\n this.panning = true;\n switch (this.selection_mode) {\n case \"add\": {\n _super.prototype._pan_start.call(this, ev);\n break;\n }\n case \"drag\": {\n this._drag_start(ev);\n break;\n }\n case \"resize\": {\n break;\n }\n }\n };\n ParallelSelectionView.prototype._pan = function (ev) {\n switch (this.selection_mode) {\n case \"add\": {\n _super.prototype._pan.call(this, ev);\n break;\n }\n case \"drag\": {\n this._drag(ev);\n break;\n }\n case \"resize\": {\n break;\n }\n }\n };\n ParallelSelectionView.prototype._pan_end = function (ev) {\n switch (this.selection_mode) {\n case \"add\": {\n _super.prototype._pan_end.call(this, ev);\n break;\n }\n case \"drag\": {\n this._drag_stop(ev);\n break;\n }\n case \"resize\": {\n break;\n }\n }\n this.panning = false;\n };\n ParallelSelectionView.prototype._move = function (ev) {\n //Switch mode\n if (this.panning) {\n return;\n }\n this.ind_active_box = this._hit_test_boxes(ev.sx, ev.sy);\n if (this.ind_active_box != null) {\n this.selection_mode = \"drag\";\n }\n else {\n this.selection_mode = \"add\";\n }\n };\n ParallelSelectionView.prototype._doubletap = function (_ev) {\n var _this = this;\n //delete box on double tap\n if (this.ind_active_box != null) {\n this.cds_select.columns().forEach(function (key) {\n _this.cds_select.get_array(key).splice(_this.ind_active_box, 1);\n });\n this._delete_selection_indices(this.ind_active_box);\n this._emit_cds_changes(this.cds_select);\n }\n };\n ParallelSelectionView.prototype._keyup = function (ev) {\n var _this = this;\n if (ev.keyCode == dom_1.Keys.Esc) {\n var nelems_1 = this.cds_select.get_length();\n if (nelems_1 != null) {\n this.cds_select.columns().forEach(function (key) {\n _this.cds_select.get_array(key).splice(0, nelems_1);\n });\n this.selection_indices.splice(0, nelems_1);\n this._emit_cds_changes(this.cds_select);\n }\n this.plot_view.request_render();\n }\n };\n ParallelSelectionView.prototype._update_data_selection = function () {\n var selection_indices = [];\n if (this.selection_indices.length > 0) {\n var combined_selections = combineByKey('data_idx', this.selection_indices);\n selection_indices = array_1.intersection.apply(void 0, [array_1.union.apply(void 0, combined_selections[0].indices)].concat(combined_selections.slice(1).map(function (elem) { return array_1.union.apply(void 0, elem.indices); })));\n }\n this.cds_data.selected.indices = selection_indices;\n this.cds_data.change.emit();\n };\n ParallelSelectionView.prototype._make_selection_indices = function (indices, _a) {\n var _this = this;\n var _b;\n var y0 = _a[0], y1 = _a[1];\n (_b = this.selection_indices).push.apply(_b, indices.map(function (index) {\n return {\n data_idx: index,\n indices: find_indices_in(_this.ydataT[index], [y0, y1]),\n };\n }));\n };\n ParallelSelectionView.prototype._update_selection_indices = function (index, _a) {\n var y0 = _a[0], y1 = _a[1];\n this.selection_indices[index].indices = find_indices_in(this.ydataT[this.selection_indices[index].data_idx], [y0, y1]);\n };\n ParallelSelectionView.prototype._delete_selection_indices = function (index) {\n this.selection_indices.splice(index, 1);\n };\n ParallelSelectionView.prototype._make_box_select = function (xs, _a) {\n var _this = this;\n var y0 = _a[0], y1 = _a[1];\n y0 = Math.max(0, y0);\n y1 = Math.min(1, y1);\n var y = (y0 + y1) / 2.;\n var w = this._box_width;\n var h = y1 - y0;\n var _b = this._cds_select_keys, xkey = _b.xkey, ykey = _b.ykey, wkey = _b.wkey, hkey = _b.hkey;\n xs.forEach(function (x) {\n if (xkey)\n _this.cds_select.get_array(xkey).push(x);\n if (ykey)\n _this.cds_select.get_array(ykey).push(y);\n if (wkey)\n _this.cds_select.get_array(wkey).push(w);\n if (hkey)\n _this.cds_select.get_array(hkey).push(h);\n });\n this._emit_cds_changes(this.cds_select);\n };\n ParallelSelectionView.prototype._do_select = function (_a, _b, _final, _append) {\n var sx0 = _a[0], sx1 = _a[1];\n var sy0 = _b[0], sy1 = _b[1];\n if (_final === void 0) { _final = true; }\n if (_append === void 0) { _append = true; }\n // Get selection bbox in the data space\n var _c = this.xscale.r_invert(sx0, sx1), x0 = _c[0], x1 = _c[1];\n var _d = this.yscale.r_invert(sy0, sy1), y0 = _d[0], y1 = _d[1];\n var x_indices = find_indices_in(this.xdata, [x0, x1]);\n var xs = index_array(this.xdata, x_indices);\n this._make_selection_indices(x_indices, [y0, y1]);\n this._make_box_select(xs, [y0, y1]);\n };\n return ParallelSelectionView;\n }(box_select_tool_1.BoxSelectToolView));\n exports.ParallelSelectionView = ParallelSelectionView;\n var ParallelSelectionTool = /** @class */ (function (_super) {\n __extends(ParallelSelectionTool, _super);\n function ParallelSelectionTool() {\n var _this = _super !== null && _super.apply(this, arguments) || this;\n _this.tool_name = \"Parallel Selection\";\n //override event_type property define in BoxSelectTool\n _this.event_type = [\"tap\", \"pan\", \"move\"];\n return _this;\n }\n ParallelSelectionTool.initClass = function () {\n this.prototype.type = \"ParallelSelectionTool\";\n this.prototype.default_view = ParallelSelectionView;\n this.define({\n renderer_select: [p.Any],\n renderer_data: [p.Any],\n box_width: [p.Number, 30],\n });\n };\n return ParallelSelectionTool;\n }(box_select_tool_1.BoxSelectTool));\n exports.ParallelSelectionTool = ParallelSelectionTool;\n ParallelSelectionTool.initClass();\n\n }\n }, \"custom/main\");\n ;\n });\n\n },\n function(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n \n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }if (force === true) {\n display_loaded();\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n } else if (force !== true) {\n var cell = $(document.getElementById(\"1246\")).parents('.cell').data().cell;\n cell.output_area.append_execute_result(NB_LOAD_WARNING)\n }\n\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));" - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "ename": "ValueError", - "evalue": "\"Invalid object to show. The object to passed to show must be one of:\n\n* a LayoutDOM (e.g. a Plot or Widget or Layout)\n* a Bokeh Application\n* a callable suitable to an application FunctionHandler\n", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mcave\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpimp_forward_selection\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;32m~/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/cave/cavefacade.py\u001b[0m in \u001b[0;36mwrap\u001b[0;34m(self, d, *args, **kw)\u001b[0m\n\u001b[1;32m 67\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshow_jupyter\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 68\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 69\u001b[0;31m \u001b[0manalyzer\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_jupyter\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 70\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mImportError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0merr\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 71\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlogger\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdebug\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0merr\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/cave/analyzer/base_analyzer.py\u001b[0m in \u001b[0;36mget_jupyter\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 96\u001b[0m \u001b[0moutput_notebook\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 97\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mbokeh_plot\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mbokeh_plots\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 98\u001b[0;31m \u001b[0mshow\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbokeh_plot\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 99\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 100\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mIPython\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcore\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdisplay\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mHTML\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdisplay\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/bokeh/io/showing.py\u001b[0m in \u001b[0;36mshow\u001b[0;34m(obj, browser, new, notebook_handle, notebook_url, **kw)\u001b[0m\n\u001b[1;32m 134\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 135\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mobj\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mLayoutDOM\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0mis_application\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0mcallable\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mobj\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 136\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0m_BAD_SHOW_MSG\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 137\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 138\u001b[0m \u001b[0;31m# TODO (bev) check callable signature more thoroughly\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mValueError\u001b[0m: \"Invalid object to show. The object to passed to show must be one of:\n\n* a LayoutDOM (e.g. a Plot or Widget or Layout)\n* a Bokeh Application\n* a callable suitable to an application FunctionHandler\n" - ] - } - ], - "source": [ - "cave.pimp_forward_selection()" + "cave.compare_default_incumbent()" ] }, { @@ -3655,7 +159,7 @@ "metadata": {}, "outputs": [], "source": [ - "cave.cave_ablation()" + "cave.performance_table()" ] }, { From e035294599835430a167d36769bbfe95f8c54521 Mon Sep 17 00:00:00 2001 From: Jessica Borja Date: Wed, 10 Mar 2021 11:47:47 +0100 Subject: [PATCH 03/22] mdpp to cave --- mdp_playground/analysis/mdpp_to_cave.py | 26 +- plot_experiments.ipynb | 4988 ++++++++++++++++++++++- 2 files changed, 4996 insertions(+), 18 deletions(-) diff --git a/mdp_playground/analysis/mdpp_to_cave.py b/mdp_playground/analysis/mdpp_to_cave.py index 180f468..957fb86 100644 --- a/mdp_playground/analysis/mdpp_to_cave.py +++ b/mdp_playground/analysis/mdpp_to_cave.py @@ -16,19 +16,22 @@ def _create_configspace_json(self, stats_pd, var_configs): "python_module_version": "0.4.11", "json_format_version": 0.1} for param in var_configs: - param_config = {"name": param, - "type": "uniform_int", - } + param_config = {"name": param} var_type = str( type(stats_pd[param].iloc[0]) ) if("int" in var_type or "bool" in var_type): param_config["lower"] = int( stats_pd[param].min() ) param_config["upper"] = int( stats_pd[param].max() ) param_config["default"] = int(param_config["lower"] + param_config["upper"]//2) param_config["type"] = "uniform_int" - else:#Float + elif('str' in var_type): + # Categorical + param_config["type"] = "categorical" + param_config["choices"] = list(stats_pd['conv_filters'].unique()) + param_config["default"] = param_config["choices"][0] + else: # Float param_config["lower"] = float( stats_pd[param].min() ) param_config["upper"] = float( stats_pd[param].max() ) - param_config["default"] = (param_config["lower"] + param_config["upper"])//2 + param_config["default"] = (param_config["lower"] + param_config["upper"])/2 param_config["type"] = "uniform_float" if "lr" in param: @@ -70,13 +73,11 @@ def join_files(self, file_prefix, file_suffix): byte_string = curr_file.read() newline_count = byte_string.count(10) num_diff_lines.append(newline_count) - # if newline_count != 21 and file_suffix == '.csv': #hack to check only train files and not eval - # warnings.warn('Expected 21 \\n chars in each stats file because we usually write stats every 1k timesteps for 20k timesteps. However, this can easily differ, e.g., for TD3 and DDPG where learning starts at 2k timesteps and there is 1 less \\n. Got only: ' + str(newline_count) + ' in file: ' + str(i)) combined_file.write(byte_string) else: break i += 1 - print(str(i) + " files were combined into 1 for file:" + file_prefix + '_n' + file_suffix) + print(str(i) + " files were combined into 1 for file:" + file_prefix + file_suffix) # print("Files missing for config_nums:", missing_configs, ". Did you pass the right value for max_total_configs as an argument?") # print("Unique line count values:", np.unique(num_diff_lines)) if i==0: @@ -202,7 +203,11 @@ def to_bohb_results(self, dir_name, exp_name): #configs.json config_lst = [config_id] for name in var_configs: - config_dict[name] = stats_pd[name].iloc[group_labels[0]].item() + value = stats_pd[name].iloc[group_labels[0]] + if(isinstance(value, str)): + config_dict[name] = value + else: + config_dict[name] = value.item() config_lst.append(config_dict) config_lst.append({"model_based_pick": False}) diff_configs_lst.append(config_lst) @@ -236,8 +241,7 @@ def to_bohb_results(self, dir_name, exp_name): if __name__ == "__main__": dir_name = '../../../mdp_files/' - exp_name = 'rainbow_image_representations_tune_hps_cave_analysis' - dir_name += exp_name + exp_name = 'dqn_seq_del' from cave.cavefacade import CAVE import os diff --git a/plot_experiments.ipynb b/plot_experiments.ipynb index 980dc18..8115361 100644 --- a/plot_experiments.ipynb +++ b/plot_experiments.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -117,10 +117,35 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/sklearn/utils/deprecation.py:143: FutureWarning: The sklearn.metrics.regression module is deprecated in version 0.22 and will be removed in version 0.24. The corresponding classes / functions should instead be imported from sklearn.metrics. Anything that cannot be imported from sklearn.metrics is now part of the private API.\n", + " warnings.warn(message, FutureWarning)\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[1;31mLoading data from a sequential run/already combined runs of experiment configurations.\u001b[0;0m\n" + ] + } + ], "source": [ + "# Setup to analyse an MDP Playground experiment\n", + "from mdp_playground.analysis import MDPP_Analysis\n", + "# Set dir_name to the location where the CSV files from running an experiment were saved\n", + "dir_name = '../mdp_files/'\n", + "# Set exp_name to the name that was given to the experiment when running it\n", + "exp_name = 'dqn_seq_del'\n", + "# Set the following to True to save PDFs of plots that you generate below\n", + "save_fig = True\n", + "\n", "from cave.cavefacade import CAVE\n", "from mdp_playground.analysis.mdpp_to_cave import MDPPToCave\n", "import os\n", @@ -130,7 +155,7 @@ "mdpp_cave = MDPPToCave(output_dir)\n", "cave_input_file = mdpp_cave.to_bohb_results(dir_name, exp_name)\n", "\n", - "cave_input_file = \"../mdpp_to_cave/dqn_seq_del\"\n", + "cave_input_file = \"../mdpp_to_cave/%s\"%exp_name\n", "\n", "# Similarly, as an example, cave will ouput it's results \n", "# to the same directory as cave's input files\n", @@ -141,7 +166,7 @@ " ta_exec_dir = [cave_input_file],\n", " file_format = \"BOHB\",\n", " show_jupyter=True,\n", - " )" + " )\n" ] }, { @@ -162,20 +187,4969 @@ "cave.performance_table()" ] }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "/* global mpl */\n", + "window.mpl = {};\n", + "\n", + "mpl.get_websocket_type = function () {\n", + " if (typeof WebSocket !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof MozWebSocket !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert(\n", + " 'Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.'\n", + " );\n", + " }\n", + "};\n", + "\n", + "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = this.ws.binaryType !== undefined;\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById('mpl-warnings');\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent =\n", + " 'This browser does not support binary websocket messages. ' +\n", + " 'Performance may be slow.';\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = document.createElement('div');\n", + " this.root.setAttribute('style', 'display: inline-block');\n", + " this._root_extra_style(this.root);\n", + "\n", + " parent_element.appendChild(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message('supports_binary', { value: fig.supports_binary });\n", + " fig.send_message('send_image_mode', {});\n", + " if (fig.ratio !== 1) {\n", + " fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n", + " }\n", + " fig.send_message('refresh', {});\n", + " };\n", + "\n", + " this.imageObj.onload = function () {\n", + " if (fig.image_mode === 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function () {\n", + " fig.ws.close();\n", + " };\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "};\n", + "\n", + "mpl.figure.prototype._init_header = function () {\n", + " var titlebar = document.createElement('div');\n", + " titlebar.classList =\n", + " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", + " var titletext = document.createElement('div');\n", + " titletext.classList = 'ui-dialog-title';\n", + " titletext.setAttribute(\n", + " 'style',\n", + " 'width: 100%; text-align: center; padding: 3px;'\n", + " );\n", + " titlebar.appendChild(titletext);\n", + " this.root.appendChild(titlebar);\n", + " this.header = titletext;\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._init_canvas = function () {\n", + " var fig = this;\n", + "\n", + " var canvas_div = (this.canvas_div = document.createElement('div'));\n", + " canvas_div.setAttribute(\n", + " 'style',\n", + " 'border: 1px solid #ddd;' +\n", + " 'box-sizing: content-box;' +\n", + " 'clear: both;' +\n", + " 'min-height: 1px;' +\n", + " 'min-width: 1px;' +\n", + " 'outline: 0;' +\n", + " 'overflow: hidden;' +\n", + " 'position: relative;' +\n", + " 'resize: both;'\n", + " );\n", + "\n", + " function on_keyboard_event_closure(name) {\n", + " return function (event) {\n", + " return fig.key_event(event, name);\n", + " };\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'keydown',\n", + " on_keyboard_event_closure('key_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'keyup',\n", + " on_keyboard_event_closure('key_release')\n", + " );\n", + "\n", + " this._canvas_extra_style(canvas_div);\n", + " this.root.appendChild(canvas_div);\n", + "\n", + " var canvas = (this.canvas = document.createElement('canvas'));\n", + " canvas.classList.add('mpl-canvas');\n", + " canvas.setAttribute('style', 'box-sizing: content-box;');\n", + "\n", + " this.context = canvas.getContext('2d');\n", + "\n", + " var backingStore =\n", + " this.context.backingStorePixelRatio ||\n", + " this.context.webkitBackingStorePixelRatio ||\n", + " this.context.mozBackingStorePixelRatio ||\n", + " this.context.msBackingStorePixelRatio ||\n", + " this.context.oBackingStorePixelRatio ||\n", + " this.context.backingStorePixelRatio ||\n", + " 1;\n", + "\n", + " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", + " 'canvas'\n", + " ));\n", + " rubberband_canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n", + " );\n", + "\n", + " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", + " if (this.ResizeObserver === undefined) {\n", + " if (window.ResizeObserver !== undefined) {\n", + " this.ResizeObserver = window.ResizeObserver;\n", + " } else {\n", + " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", + " this.ResizeObserver = obs.ResizeObserver;\n", + " }\n", + " }\n", + "\n", + " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", + " var nentries = entries.length;\n", + " for (var i = 0; i < nentries; i++) {\n", + " var entry = entries[i];\n", + " var width, height;\n", + " if (entry.contentBoxSize) {\n", + " if (entry.contentBoxSize instanceof Array) {\n", + " // Chrome 84 implements new version of spec.\n", + " width = entry.contentBoxSize[0].inlineSize;\n", + " height = entry.contentBoxSize[0].blockSize;\n", + " } else {\n", + " // Firefox implements old version of spec.\n", + " width = entry.contentBoxSize.inlineSize;\n", + " height = entry.contentBoxSize.blockSize;\n", + " }\n", + " } else {\n", + " // Chrome <84 implements even older version of spec.\n", + " width = entry.contentRect.width;\n", + " height = entry.contentRect.height;\n", + " }\n", + "\n", + " // Keep the size of the canvas and rubber band canvas in sync with\n", + " // the canvas container.\n", + " if (entry.devicePixelContentBoxSize) {\n", + " // Chrome 84 implements new version of spec.\n", + " canvas.setAttribute(\n", + " 'width',\n", + " entry.devicePixelContentBoxSize[0].inlineSize\n", + " );\n", + " canvas.setAttribute(\n", + " 'height',\n", + " entry.devicePixelContentBoxSize[0].blockSize\n", + " );\n", + " } else {\n", + " canvas.setAttribute('width', width * fig.ratio);\n", + " canvas.setAttribute('height', height * fig.ratio);\n", + " }\n", + " canvas.setAttribute(\n", + " 'style',\n", + " 'width: ' + width + 'px; height: ' + height + 'px;'\n", + " );\n", + "\n", + " rubberband_canvas.setAttribute('width', width);\n", + " rubberband_canvas.setAttribute('height', height);\n", + "\n", + " // And update the size in Python. We ignore the initial 0/0 size\n", + " // that occurs as the element is placed into the DOM, which should\n", + " // otherwise not happen due to the minimum size styling.\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", + " fig.request_resize(width, height);\n", + " }\n", + " }\n", + " });\n", + " this.resizeObserverInstance.observe(canvas_div);\n", + "\n", + " function on_mouse_event_closure(name) {\n", + " return function (event) {\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " }\n", + "\n", + " rubberband_canvas.addEventListener(\n", + " 'mousedown',\n", + " on_mouse_event_closure('button_press')\n", + " );\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseup',\n", + " on_mouse_event_closure('button_release')\n", + " );\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband_canvas.addEventListener(\n", + " 'mousemove',\n", + " on_mouse_event_closure('motion_notify')\n", + " );\n", + "\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseenter',\n", + " on_mouse_event_closure('figure_enter')\n", + " );\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseleave',\n", + " on_mouse_event_closure('figure_leave')\n", + " );\n", + "\n", + " canvas_div.addEventListener('wheel', function (event) {\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " on_mouse_event_closure('scroll')(event);\n", + " });\n", + "\n", + " canvas_div.appendChild(canvas);\n", + " canvas_div.appendChild(rubberband_canvas);\n", + "\n", + " this.rubberband_context = rubberband_canvas.getContext('2d');\n", + " this.rubberband_context.strokeStyle = '#000000';\n", + "\n", + " this._resize_canvas = function (width, height, forward) {\n", + " if (forward) {\n", + " canvas_div.style.width = width + 'px';\n", + " canvas_div.style.height = height + 'px';\n", + " }\n", + " };\n", + "\n", + " // Disable right mouse context menu.\n", + " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n", + " event.preventDefault();\n", + " return false;\n", + " });\n", + "\n", + " function set_focus() {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'mpl-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " continue;\n", + " }\n", + "\n", + " var button = (fig.buttons[name] = document.createElement('button'));\n", + " button.classList = 'mpl-widget';\n", + " button.setAttribute('role', 'button');\n", + " button.setAttribute('aria-disabled', 'false');\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + "\n", + " var icon_img = document.createElement('img');\n", + " icon_img.src = '_images/' + image + '.png';\n", + " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", + " icon_img.alt = tooltip;\n", + " button.appendChild(icon_img);\n", + "\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " var fmt_picker = document.createElement('select');\n", + " fmt_picker.classList = 'mpl-widget';\n", + " toolbar.appendChild(fmt_picker);\n", + " this.format_dropdown = fmt_picker;\n", + "\n", + " for (var ind in mpl.extensions) {\n", + " var fmt = mpl.extensions[ind];\n", + " var option = document.createElement('option');\n", + " option.selected = fmt === mpl.default_extension;\n", + " option.innerHTML = fmt;\n", + " fmt_picker.appendChild(option);\n", + " }\n", + "\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "};\n", + "\n", + "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", + " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", + " // which will in turn request a refresh of the image.\n", + " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", + "};\n", + "\n", + "mpl.figure.prototype.send_message = function (type, properties) {\n", + " properties['type'] = type;\n", + " properties['figure_id'] = this.id;\n", + " this.ws.send(JSON.stringify(properties));\n", + "};\n", + "\n", + "mpl.figure.prototype.send_draw_message = function () {\n", + " if (!this.waiting) {\n", + " this.waiting = true;\n", + " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " var format_dropdown = fig.format_dropdown;\n", + " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", + " fig.ondownload(fig, format);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", + " var size = msg['size'];\n", + " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", + " fig._resize_canvas(size[0], size[1], msg['forward']);\n", + " fig.send_message('refresh', {});\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", + " var x0 = msg['x0'] / fig.ratio;\n", + " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", + " var x1 = msg['x1'] / fig.ratio;\n", + " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", + " x0 = Math.floor(x0) + 0.5;\n", + " y0 = Math.floor(y0) + 0.5;\n", + " x1 = Math.floor(x1) + 0.5;\n", + " y1 = Math.floor(y1) + 0.5;\n", + " var min_x = Math.min(x0, x1);\n", + " var min_y = Math.min(y0, y1);\n", + " var width = Math.abs(x1 - x0);\n", + " var height = Math.abs(y1 - y0);\n", + "\n", + " fig.rubberband_context.clearRect(\n", + " 0,\n", + " 0,\n", + " fig.canvas.width / fig.ratio,\n", + " fig.canvas.height / fig.ratio\n", + " );\n", + "\n", + " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", + " // Updates the figure title.\n", + " fig.header.textContent = msg['label'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", + " var cursor = msg['cursor'];\n", + " switch (cursor) {\n", + " case 0:\n", + " cursor = 'pointer';\n", + " break;\n", + " case 1:\n", + " cursor = 'default';\n", + " break;\n", + " case 2:\n", + " cursor = 'crosshair';\n", + " break;\n", + " case 3:\n", + " cursor = 'move';\n", + " break;\n", + " }\n", + " fig.rubberband_canvas.style.cursor = cursor;\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_message = function (fig, msg) {\n", + " fig.message.textContent = msg['message'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", + " // Request the server to send over a new figure.\n", + " fig.send_draw_message();\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", + " fig.image_mode = msg['mode'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", + " for (var key in msg) {\n", + " if (!(key in fig.buttons)) {\n", + " continue;\n", + " }\n", + " fig.buttons[key].disabled = !msg[key];\n", + " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", + " if (msg['mode'] === 'PAN') {\n", + " fig.buttons['Pan'].classList.add('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " } else if (msg['mode'] === 'ZOOM') {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.add('active');\n", + " } else {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Called whenever the canvas gets updated.\n", + " this.send_message('ack', {});\n", + "};\n", + "\n", + "// A function to construct a web socket function for onmessage handling.\n", + "// Called in the figure constructor.\n", + "mpl.figure.prototype._make_on_message_function = function (fig) {\n", + " return function socket_on_message(evt) {\n", + " if (evt.data instanceof Blob) {\n", + " /* FIXME: We get \"Resource interpreted as Image but\n", + " * transferred with MIME type text/plain:\" errors on\n", + " * Chrome. But how to set the MIME type? It doesn't seem\n", + " * to be part of the websocket stream */\n", + " evt.data.type = 'image/png';\n", + "\n", + " /* Free the memory for the previous frames */\n", + " if (fig.imageObj.src) {\n", + " (window.URL || window.webkitURL).revokeObjectURL(\n", + " fig.imageObj.src\n", + " );\n", + " }\n", + "\n", + " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", + " evt.data\n", + " );\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " } else if (\n", + " typeof evt.data === 'string' &&\n", + " evt.data.slice(0, 21) === 'data:image/png;base64'\n", + " ) {\n", + " fig.imageObj.src = evt.data;\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " }\n", + "\n", + " var msg = JSON.parse(evt.data);\n", + " var msg_type = msg['type'];\n", + "\n", + " // Call the \"handle_{type}\" callback, which takes\n", + " // the figure and JSON message as its only arguments.\n", + " try {\n", + " var callback = fig['handle_' + msg_type];\n", + " } catch (e) {\n", + " console.log(\n", + " \"No handler for the '\" + msg_type + \"' message type: \",\n", + " msg\n", + " );\n", + " return;\n", + " }\n", + "\n", + " if (callback) {\n", + " try {\n", + " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", + " callback(fig, msg);\n", + " } catch (e) {\n", + " console.log(\n", + " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", + " e,\n", + " e.stack,\n", + " msg\n", + " );\n", + " }\n", + " }\n", + " };\n", + "};\n", + "\n", + "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", + "mpl.findpos = function (e) {\n", + " //this section is from http://www.quirksmode.org/js/events_properties.html\n", + " var targ;\n", + " if (!e) {\n", + " e = window.event;\n", + " }\n", + " if (e.target) {\n", + " targ = e.target;\n", + " } else if (e.srcElement) {\n", + " targ = e.srcElement;\n", + " }\n", + " if (targ.nodeType === 3) {\n", + " // defeat Safari bug\n", + " targ = targ.parentNode;\n", + " }\n", + "\n", + " // pageX,Y are the mouse positions relative to the document\n", + " var boundingRect = targ.getBoundingClientRect();\n", + " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n", + " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n", + "\n", + " return { x: x, y: y };\n", + "};\n", + "\n", + "/*\n", + " * return a copy of an object with only non-object keys\n", + " * we need this to avoid circular references\n", + " * http://stackoverflow.com/a/24161582/3208463\n", + " */\n", + "function simpleKeys(original) {\n", + " return Object.keys(original).reduce(function (obj, key) {\n", + " if (typeof original[key] !== 'object') {\n", + " obj[key] = original[key];\n", + " }\n", + " return obj;\n", + " }, {});\n", + "}\n", + "\n", + "mpl.figure.prototype.mouse_event = function (event, name) {\n", + " var canvas_pos = mpl.findpos(event);\n", + "\n", + " if (name === 'button_press') {\n", + " this.canvas.focus();\n", + " this.canvas_div.focus();\n", + " }\n", + "\n", + " var x = canvas_pos.x * this.ratio;\n", + " var y = canvas_pos.y * this.ratio;\n", + "\n", + " this.send_message(name, {\n", + " x: x,\n", + " y: y,\n", + " button: event.button,\n", + " step: event.step,\n", + " guiEvent: simpleKeys(event),\n", + " });\n", + "\n", + " /* This prevents the web browser from automatically changing to\n", + " * the text insertion cursor when the button is pressed. We want\n", + " * to control all of the cursor setting manually through the\n", + " * 'cursor' event from matplotlib */\n", + " event.preventDefault();\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", + " // Handle any extra behaviour associated with a key event\n", + "};\n", + "\n", + "mpl.figure.prototype.key_event = function (event, name) {\n", + " // Prevent repeat events\n", + " if (name === 'key_press') {\n", + " if (event.which === this._key) {\n", + " return;\n", + " } else {\n", + " this._key = event.which;\n", + " }\n", + " }\n", + " if (name === 'key_release') {\n", + " this._key = null;\n", + " }\n", + "\n", + " var value = '';\n", + " if (event.ctrlKey && event.which !== 17) {\n", + " value += 'ctrl+';\n", + " }\n", + " if (event.altKey && event.which !== 18) {\n", + " value += 'alt+';\n", + " }\n", + " if (event.shiftKey && event.which !== 16) {\n", + " value += 'shift+';\n", + " }\n", + "\n", + " value += 'k';\n", + " value += event.which.toString();\n", + "\n", + " this._key_event_extra(event, name);\n", + "\n", + " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", + " if (name === 'download') {\n", + " this.handle_save(this, null);\n", + " } else {\n", + " this.send_message('toolbar_button', { name: name });\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", + " this.message.textContent = tooltip;\n", + "};\n", + "\n", + "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", + "// prettier-ignore\n", + "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", + "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", + "\n", + "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", + "\n", + "mpl.default_extension = \"png\";/* global mpl */\n", + "\n", + "var comm_websocket_adapter = function (comm) {\n", + " // Create a \"websocket\"-like object which calls the given IPython comm\n", + " // object with the appropriate methods. Currently this is a non binary\n", + " // socket, so there is still some room for performance tuning.\n", + " var ws = {};\n", + "\n", + " ws.close = function () {\n", + " comm.close();\n", + " };\n", + " ws.send = function (m) {\n", + " //console.log('sending', m);\n", + " comm.send(m);\n", + " };\n", + " // Register the callback with on_msg.\n", + " comm.on_msg(function (msg) {\n", + " //console.log('receiving', msg['content']['data'], msg);\n", + " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", + " ws.onmessage(msg['content']['data']);\n", + " });\n", + " return ws;\n", + "};\n", + "\n", + "mpl.mpl_figure_comm = function (comm, msg) {\n", + " // This is the function which gets called when the mpl process\n", + " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", + "\n", + " var id = msg.content.data.id;\n", + " // Get hold of the div created by the display call when the Comm\n", + " // socket was opened in Python.\n", + " var element = document.getElementById(id);\n", + " var ws_proxy = comm_websocket_adapter(comm);\n", + "\n", + " function ondownload(figure, _format) {\n", + " window.open(figure.canvas.toDataURL());\n", + " }\n", + "\n", + " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", + "\n", + " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", + " // web socket which is closed, not our websocket->open comm proxy.\n", + " ws_proxy.onopen();\n", + "\n", + " fig.parent_element = element;\n", + " fig.cell_info = mpl.find_output_cell(\"
\");\n", + " if (!fig.cell_info) {\n", + " console.error('Failed to find cell for figure', id, fig);\n", + " return;\n", + " }\n", + " fig.cell_info[0].output_area.element.on(\n", + " 'cleared',\n", + " { fig: fig },\n", + " fig._remove_fig_handler\n", + " );\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_close = function (fig, msg) {\n", + " var width = fig.canvas.width / fig.ratio;\n", + " fig.cell_info[0].output_area.element.off(\n", + " 'cleared',\n", + " fig._remove_fig_handler\n", + " );\n", + " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", + "\n", + " // Update the output cell to use the data from the current canvas.\n", + " fig.push_to_output();\n", + " var dataURL = fig.canvas.toDataURL();\n", + " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", + " // the notebook keyboard shortcuts fail.\n", + " IPython.keyboard_manager.enable();\n", + " fig.parent_element.innerHTML =\n", + " '';\n", + " fig.close_ws(fig, msg);\n", + "};\n", + "\n", + "mpl.figure.prototype.close_ws = function (fig, msg) {\n", + " fig.send_message('closing', msg);\n", + " // fig.ws.close()\n", + "};\n", + "\n", + "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", + " // Turn the data on the canvas into data in the output cell.\n", + " var width = this.canvas.width / this.ratio;\n", + " var dataURL = this.canvas.toDataURL();\n", + " this.cell_info[1]['text/html'] =\n", + " '';\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Tell IPython that the notebook contents must change.\n", + " IPython.notebook.set_dirty(true);\n", + " this.send_message('ack', {});\n", + " var fig = this;\n", + " // Wait a second, then push the new image to the DOM so\n", + " // that it is saved nicely (might be nice to debounce this).\n", + " setTimeout(function () {\n", + " fig.push_to_output();\n", + " }, 1000);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'btn-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " var button;\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " continue;\n", + " }\n", + "\n", + " button = fig.buttons[name] = document.createElement('button');\n", + " button.classList = 'btn btn-default';\n", + " button.href = '#';\n", + " button.title = name;\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message pull-right';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = document.createElement('div');\n", + " buttongrp.classList = 'btn-group inline pull-right';\n", + " button = document.createElement('button');\n", + " button.classList = 'btn btn-mini btn-primary';\n", + " button.href = '#';\n", + " button.title = 'Stop Interaction';\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', function (_evt) {\n", + " fig.handle_close(fig, {});\n", + " });\n", + " button.addEventListener(\n", + " 'mouseover',\n", + " on_mouseover_closure('Stop Interaction')\n", + " );\n", + " buttongrp.appendChild(button);\n", + " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", + " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", + "};\n", + "\n", + "mpl.figure.prototype._remove_fig_handler = function (event) {\n", + " var fig = event.data.fig;\n", + " if (event.target !== this) {\n", + " // Ignore bubbled events from children.\n", + " return;\n", + " }\n", + " fig.close_ws(fig, {});\n", + "};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (el) {\n", + " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (el) {\n", + " // this is important to make the div 'focusable\n", + " el.setAttribute('tabindex', 0);\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " } else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager) {\n", + " manager = IPython.keyboard_manager;\n", + " }\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which === 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " fig.ondownload(fig, null);\n", + "};\n", + "\n", + "mpl.find_output_cell = function (html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i = 0; i < ncells; i++) {\n", + " var cell = cells[i];\n", + " if (cell.cell_type === 'code') {\n", + " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", + " var data = cell.output_area.outputs[j];\n", + " if (data.data) {\n", + " // IPython >= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] === html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "};\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel !== null) {\n", + " IPython.notebook.kernel.comm_manager.register_target(\n", + " 'matplotlib',\n", + " mpl.mpl_figure_comm\n", + " );\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "/* global mpl */\n", + "window.mpl = {};\n", + "\n", + "mpl.get_websocket_type = function () {\n", + " if (typeof WebSocket !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof MozWebSocket !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert(\n", + " 'Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.'\n", + " );\n", + " }\n", + "};\n", + "\n", + "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = this.ws.binaryType !== undefined;\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById('mpl-warnings');\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent =\n", + " 'This browser does not support binary websocket messages. ' +\n", + " 'Performance may be slow.';\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = document.createElement('div');\n", + " this.root.setAttribute('style', 'display: inline-block');\n", + " this._root_extra_style(this.root);\n", + "\n", + " parent_element.appendChild(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message('supports_binary', { value: fig.supports_binary });\n", + " fig.send_message('send_image_mode', {});\n", + " if (fig.ratio !== 1) {\n", + " fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n", + " }\n", + " fig.send_message('refresh', {});\n", + " };\n", + "\n", + " this.imageObj.onload = function () {\n", + " if (fig.image_mode === 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function () {\n", + " fig.ws.close();\n", + " };\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "};\n", + "\n", + "mpl.figure.prototype._init_header = function () {\n", + " var titlebar = document.createElement('div');\n", + " titlebar.classList =\n", + " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", + " var titletext = document.createElement('div');\n", + " titletext.classList = 'ui-dialog-title';\n", + " titletext.setAttribute(\n", + " 'style',\n", + " 'width: 100%; text-align: center; padding: 3px;'\n", + " );\n", + " titlebar.appendChild(titletext);\n", + " this.root.appendChild(titlebar);\n", + " this.header = titletext;\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._init_canvas = function () {\n", + " var fig = this;\n", + "\n", + " var canvas_div = (this.canvas_div = document.createElement('div'));\n", + " canvas_div.setAttribute(\n", + " 'style',\n", + " 'border: 1px solid #ddd;' +\n", + " 'box-sizing: content-box;' +\n", + " 'clear: both;' +\n", + " 'min-height: 1px;' +\n", + " 'min-width: 1px;' +\n", + " 'outline: 0;' +\n", + " 'overflow: hidden;' +\n", + " 'position: relative;' +\n", + " 'resize: both;'\n", + " );\n", + "\n", + " function on_keyboard_event_closure(name) {\n", + " return function (event) {\n", + " return fig.key_event(event, name);\n", + " };\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'keydown',\n", + " on_keyboard_event_closure('key_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'keyup',\n", + " on_keyboard_event_closure('key_release')\n", + " );\n", + "\n", + " this._canvas_extra_style(canvas_div);\n", + " this.root.appendChild(canvas_div);\n", + "\n", + " var canvas = (this.canvas = document.createElement('canvas'));\n", + " canvas.classList.add('mpl-canvas');\n", + " canvas.setAttribute('style', 'box-sizing: content-box;');\n", + "\n", + " this.context = canvas.getContext('2d');\n", + "\n", + " var backingStore =\n", + " this.context.backingStorePixelRatio ||\n", + " this.context.webkitBackingStorePixelRatio ||\n", + " this.context.mozBackingStorePixelRatio ||\n", + " this.context.msBackingStorePixelRatio ||\n", + " this.context.oBackingStorePixelRatio ||\n", + " this.context.backingStorePixelRatio ||\n", + " 1;\n", + "\n", + " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", + " 'canvas'\n", + " ));\n", + " rubberband_canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n", + " );\n", + "\n", + " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", + " if (this.ResizeObserver === undefined) {\n", + " if (window.ResizeObserver !== undefined) {\n", + " this.ResizeObserver = window.ResizeObserver;\n", + " } else {\n", + " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", + " this.ResizeObserver = obs.ResizeObserver;\n", + " }\n", + " }\n", + "\n", + " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", + " var nentries = entries.length;\n", + " for (var i = 0; i < nentries; i++) {\n", + " var entry = entries[i];\n", + " var width, height;\n", + " if (entry.contentBoxSize) {\n", + " if (entry.contentBoxSize instanceof Array) {\n", + " // Chrome 84 implements new version of spec.\n", + " width = entry.contentBoxSize[0].inlineSize;\n", + " height = entry.contentBoxSize[0].blockSize;\n", + " } else {\n", + " // Firefox implements old version of spec.\n", + " width = entry.contentBoxSize.inlineSize;\n", + " height = entry.contentBoxSize.blockSize;\n", + " }\n", + " } else {\n", + " // Chrome <84 implements even older version of spec.\n", + " width = entry.contentRect.width;\n", + " height = entry.contentRect.height;\n", + " }\n", + "\n", + " // Keep the size of the canvas and rubber band canvas in sync with\n", + " // the canvas container.\n", + " if (entry.devicePixelContentBoxSize) {\n", + " // Chrome 84 implements new version of spec.\n", + " canvas.setAttribute(\n", + " 'width',\n", + " entry.devicePixelContentBoxSize[0].inlineSize\n", + " );\n", + " canvas.setAttribute(\n", + " 'height',\n", + " entry.devicePixelContentBoxSize[0].blockSize\n", + " );\n", + " } else {\n", + " canvas.setAttribute('width', width * fig.ratio);\n", + " canvas.setAttribute('height', height * fig.ratio);\n", + " }\n", + " canvas.setAttribute(\n", + " 'style',\n", + " 'width: ' + width + 'px; height: ' + height + 'px;'\n", + " );\n", + "\n", + " rubberband_canvas.setAttribute('width', width);\n", + " rubberband_canvas.setAttribute('height', height);\n", + "\n", + " // And update the size in Python. We ignore the initial 0/0 size\n", + " // that occurs as the element is placed into the DOM, which should\n", + " // otherwise not happen due to the minimum size styling.\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", + " fig.request_resize(width, height);\n", + " }\n", + " }\n", + " });\n", + " this.resizeObserverInstance.observe(canvas_div);\n", + "\n", + " function on_mouse_event_closure(name) {\n", + " return function (event) {\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " }\n", + "\n", + " rubberband_canvas.addEventListener(\n", + " 'mousedown',\n", + " on_mouse_event_closure('button_press')\n", + " );\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseup',\n", + " on_mouse_event_closure('button_release')\n", + " );\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband_canvas.addEventListener(\n", + " 'mousemove',\n", + " on_mouse_event_closure('motion_notify')\n", + " );\n", + "\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseenter',\n", + " on_mouse_event_closure('figure_enter')\n", + " );\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseleave',\n", + " on_mouse_event_closure('figure_leave')\n", + " );\n", + "\n", + " canvas_div.addEventListener('wheel', function (event) {\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " on_mouse_event_closure('scroll')(event);\n", + " });\n", + "\n", + " canvas_div.appendChild(canvas);\n", + " canvas_div.appendChild(rubberband_canvas);\n", + "\n", + " this.rubberband_context = rubberband_canvas.getContext('2d');\n", + " this.rubberband_context.strokeStyle = '#000000';\n", + "\n", + " this._resize_canvas = function (width, height, forward) {\n", + " if (forward) {\n", + " canvas_div.style.width = width + 'px';\n", + " canvas_div.style.height = height + 'px';\n", + " }\n", + " };\n", + "\n", + " // Disable right mouse context menu.\n", + " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n", + " event.preventDefault();\n", + " return false;\n", + " });\n", + "\n", + " function set_focus() {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'mpl-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " continue;\n", + " }\n", + "\n", + " var button = (fig.buttons[name] = document.createElement('button'));\n", + " button.classList = 'mpl-widget';\n", + " button.setAttribute('role', 'button');\n", + " button.setAttribute('aria-disabled', 'false');\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + "\n", + " var icon_img = document.createElement('img');\n", + " icon_img.src = '_images/' + image + '.png';\n", + " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", + " icon_img.alt = tooltip;\n", + " button.appendChild(icon_img);\n", + "\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " var fmt_picker = document.createElement('select');\n", + " fmt_picker.classList = 'mpl-widget';\n", + " toolbar.appendChild(fmt_picker);\n", + " this.format_dropdown = fmt_picker;\n", + "\n", + " for (var ind in mpl.extensions) {\n", + " var fmt = mpl.extensions[ind];\n", + " var option = document.createElement('option');\n", + " option.selected = fmt === mpl.default_extension;\n", + " option.innerHTML = fmt;\n", + " fmt_picker.appendChild(option);\n", + " }\n", + "\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "};\n", + "\n", + "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", + " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", + " // which will in turn request a refresh of the image.\n", + " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", + "};\n", + "\n", + "mpl.figure.prototype.send_message = function (type, properties) {\n", + " properties['type'] = type;\n", + " properties['figure_id'] = this.id;\n", + " this.ws.send(JSON.stringify(properties));\n", + "};\n", + "\n", + "mpl.figure.prototype.send_draw_message = function () {\n", + " if (!this.waiting) {\n", + " this.waiting = true;\n", + " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " var format_dropdown = fig.format_dropdown;\n", + " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", + " fig.ondownload(fig, format);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", + " var size = msg['size'];\n", + " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", + " fig._resize_canvas(size[0], size[1], msg['forward']);\n", + " fig.send_message('refresh', {});\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", + " var x0 = msg['x0'] / fig.ratio;\n", + " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", + " var x1 = msg['x1'] / fig.ratio;\n", + " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", + " x0 = Math.floor(x0) + 0.5;\n", + " y0 = Math.floor(y0) + 0.5;\n", + " x1 = Math.floor(x1) + 0.5;\n", + " y1 = Math.floor(y1) + 0.5;\n", + " var min_x = Math.min(x0, x1);\n", + " var min_y = Math.min(y0, y1);\n", + " var width = Math.abs(x1 - x0);\n", + " var height = Math.abs(y1 - y0);\n", + "\n", + " fig.rubberband_context.clearRect(\n", + " 0,\n", + " 0,\n", + " fig.canvas.width / fig.ratio,\n", + " fig.canvas.height / fig.ratio\n", + " );\n", + "\n", + " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", + " // Updates the figure title.\n", + " fig.header.textContent = msg['label'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", + " var cursor = msg['cursor'];\n", + " switch (cursor) {\n", + " case 0:\n", + " cursor = 'pointer';\n", + " break;\n", + " case 1:\n", + " cursor = 'default';\n", + " break;\n", + " case 2:\n", + " cursor = 'crosshair';\n", + " break;\n", + " case 3:\n", + " cursor = 'move';\n", + " break;\n", + " }\n", + " fig.rubberband_canvas.style.cursor = cursor;\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_message = function (fig, msg) {\n", + " fig.message.textContent = msg['message'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", + " // Request the server to send over a new figure.\n", + " fig.send_draw_message();\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", + " fig.image_mode = msg['mode'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", + " for (var key in msg) {\n", + " if (!(key in fig.buttons)) {\n", + " continue;\n", + " }\n", + " fig.buttons[key].disabled = !msg[key];\n", + " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", + " if (msg['mode'] === 'PAN') {\n", + " fig.buttons['Pan'].classList.add('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " } else if (msg['mode'] === 'ZOOM') {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.add('active');\n", + " } else {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Called whenever the canvas gets updated.\n", + " this.send_message('ack', {});\n", + "};\n", + "\n", + "// A function to construct a web socket function for onmessage handling.\n", + "// Called in the figure constructor.\n", + "mpl.figure.prototype._make_on_message_function = function (fig) {\n", + " return function socket_on_message(evt) {\n", + " if (evt.data instanceof Blob) {\n", + " /* FIXME: We get \"Resource interpreted as Image but\n", + " * transferred with MIME type text/plain:\" errors on\n", + " * Chrome. But how to set the MIME type? It doesn't seem\n", + " * to be part of the websocket stream */\n", + " evt.data.type = 'image/png';\n", + "\n", + " /* Free the memory for the previous frames */\n", + " if (fig.imageObj.src) {\n", + " (window.URL || window.webkitURL).revokeObjectURL(\n", + " fig.imageObj.src\n", + " );\n", + " }\n", + "\n", + " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", + " evt.data\n", + " );\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " } else if (\n", + " typeof evt.data === 'string' &&\n", + " evt.data.slice(0, 21) === 'data:image/png;base64'\n", + " ) {\n", + " fig.imageObj.src = evt.data;\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " }\n", + "\n", + " var msg = JSON.parse(evt.data);\n", + " var msg_type = msg['type'];\n", + "\n", + " // Call the \"handle_{type}\" callback, which takes\n", + " // the figure and JSON message as its only arguments.\n", + " try {\n", + " var callback = fig['handle_' + msg_type];\n", + " } catch (e) {\n", + " console.log(\n", + " \"No handler for the '\" + msg_type + \"' message type: \",\n", + " msg\n", + " );\n", + " return;\n", + " }\n", + "\n", + " if (callback) {\n", + " try {\n", + " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", + " callback(fig, msg);\n", + " } catch (e) {\n", + " console.log(\n", + " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", + " e,\n", + " e.stack,\n", + " msg\n", + " );\n", + " }\n", + " }\n", + " };\n", + "};\n", + "\n", + "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", + "mpl.findpos = function (e) {\n", + " //this section is from http://www.quirksmode.org/js/events_properties.html\n", + " var targ;\n", + " if (!e) {\n", + " e = window.event;\n", + " }\n", + " if (e.target) {\n", + " targ = e.target;\n", + " } else if (e.srcElement) {\n", + " targ = e.srcElement;\n", + " }\n", + " if (targ.nodeType === 3) {\n", + " // defeat Safari bug\n", + " targ = targ.parentNode;\n", + " }\n", + "\n", + " // pageX,Y are the mouse positions relative to the document\n", + " var boundingRect = targ.getBoundingClientRect();\n", + " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n", + " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n", + "\n", + " return { x: x, y: y };\n", + "};\n", + "\n", + "/*\n", + " * return a copy of an object with only non-object keys\n", + " * we need this to avoid circular references\n", + " * http://stackoverflow.com/a/24161582/3208463\n", + " */\n", + "function simpleKeys(original) {\n", + " return Object.keys(original).reduce(function (obj, key) {\n", + " if (typeof original[key] !== 'object') {\n", + " obj[key] = original[key];\n", + " }\n", + " return obj;\n", + " }, {});\n", + "}\n", + "\n", + "mpl.figure.prototype.mouse_event = function (event, name) {\n", + " var canvas_pos = mpl.findpos(event);\n", + "\n", + " if (name === 'button_press') {\n", + " this.canvas.focus();\n", + " this.canvas_div.focus();\n", + " }\n", + "\n", + " var x = canvas_pos.x * this.ratio;\n", + " var y = canvas_pos.y * this.ratio;\n", + "\n", + " this.send_message(name, {\n", + " x: x,\n", + " y: y,\n", + " button: event.button,\n", + " step: event.step,\n", + " guiEvent: simpleKeys(event),\n", + " });\n", + "\n", + " /* This prevents the web browser from automatically changing to\n", + " * the text insertion cursor when the button is pressed. We want\n", + " * to control all of the cursor setting manually through the\n", + " * 'cursor' event from matplotlib */\n", + " event.preventDefault();\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", + " // Handle any extra behaviour associated with a key event\n", + "};\n", + "\n", + "mpl.figure.prototype.key_event = function (event, name) {\n", + " // Prevent repeat events\n", + " if (name === 'key_press') {\n", + " if (event.which === this._key) {\n", + " return;\n", + " } else {\n", + " this._key = event.which;\n", + " }\n", + " }\n", + " if (name === 'key_release') {\n", + " this._key = null;\n", + " }\n", + "\n", + " var value = '';\n", + " if (event.ctrlKey && event.which !== 17) {\n", + " value += 'ctrl+';\n", + " }\n", + " if (event.altKey && event.which !== 18) {\n", + " value += 'alt+';\n", + " }\n", + " if (event.shiftKey && event.which !== 16) {\n", + " value += 'shift+';\n", + " }\n", + "\n", + " value += 'k';\n", + " value += event.which.toString();\n", + "\n", + " this._key_event_extra(event, name);\n", + "\n", + " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", + " if (name === 'download') {\n", + " this.handle_save(this, null);\n", + " } else {\n", + " this.send_message('toolbar_button', { name: name });\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", + " this.message.textContent = tooltip;\n", + "};\n", + "\n", + "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", + "// prettier-ignore\n", + "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", + "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", + "\n", + "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", + "\n", + "mpl.default_extension = \"png\";/* global mpl */\n", + "\n", + "var comm_websocket_adapter = function (comm) {\n", + " // Create a \"websocket\"-like object which calls the given IPython comm\n", + " // object with the appropriate methods. Currently this is a non binary\n", + " // socket, so there is still some room for performance tuning.\n", + " var ws = {};\n", + "\n", + " ws.close = function () {\n", + " comm.close();\n", + " };\n", + " ws.send = function (m) {\n", + " //console.log('sending', m);\n", + " comm.send(m);\n", + " };\n", + " // Register the callback with on_msg.\n", + " comm.on_msg(function (msg) {\n", + " //console.log('receiving', msg['content']['data'], msg);\n", + " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", + " ws.onmessage(msg['content']['data']);\n", + " });\n", + " return ws;\n", + "};\n", + "\n", + "mpl.mpl_figure_comm = function (comm, msg) {\n", + " // This is the function which gets called when the mpl process\n", + " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", + "\n", + " var id = msg.content.data.id;\n", + " // Get hold of the div created by the display call when the Comm\n", + " // socket was opened in Python.\n", + " var element = document.getElementById(id);\n", + " var ws_proxy = comm_websocket_adapter(comm);\n", + "\n", + " function ondownload(figure, _format) {\n", + " window.open(figure.canvas.toDataURL());\n", + " }\n", + "\n", + " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", + "\n", + " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", + " // web socket which is closed, not our websocket->open comm proxy.\n", + " ws_proxy.onopen();\n", + "\n", + " fig.parent_element = element;\n", + " fig.cell_info = mpl.find_output_cell(\"
\");\n", + " if (!fig.cell_info) {\n", + " console.error('Failed to find cell for figure', id, fig);\n", + " return;\n", + " }\n", + " fig.cell_info[0].output_area.element.on(\n", + " 'cleared',\n", + " { fig: fig },\n", + " fig._remove_fig_handler\n", + " );\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_close = function (fig, msg) {\n", + " var width = fig.canvas.width / fig.ratio;\n", + " fig.cell_info[0].output_area.element.off(\n", + " 'cleared',\n", + " fig._remove_fig_handler\n", + " );\n", + " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", + "\n", + " // Update the output cell to use the data from the current canvas.\n", + " fig.push_to_output();\n", + " var dataURL = fig.canvas.toDataURL();\n", + " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", + " // the notebook keyboard shortcuts fail.\n", + " IPython.keyboard_manager.enable();\n", + " fig.parent_element.innerHTML =\n", + " '';\n", + " fig.close_ws(fig, msg);\n", + "};\n", + "\n", + "mpl.figure.prototype.close_ws = function (fig, msg) {\n", + " fig.send_message('closing', msg);\n", + " // fig.ws.close()\n", + "};\n", + "\n", + "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", + " // Turn the data on the canvas into data in the output cell.\n", + " var width = this.canvas.width / this.ratio;\n", + " var dataURL = this.canvas.toDataURL();\n", + " this.cell_info[1]['text/html'] =\n", + " '';\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Tell IPython that the notebook contents must change.\n", + " IPython.notebook.set_dirty(true);\n", + " this.send_message('ack', {});\n", + " var fig = this;\n", + " // Wait a second, then push the new image to the DOM so\n", + " // that it is saved nicely (might be nice to debounce this).\n", + " setTimeout(function () {\n", + " fig.push_to_output();\n", + " }, 1000);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'btn-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " var button;\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " continue;\n", + " }\n", + "\n", + " button = fig.buttons[name] = document.createElement('button');\n", + " button.classList = 'btn btn-default';\n", + " button.href = '#';\n", + " button.title = name;\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message pull-right';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = document.createElement('div');\n", + " buttongrp.classList = 'btn-group inline pull-right';\n", + " button = document.createElement('button');\n", + " button.classList = 'btn btn-mini btn-primary';\n", + " button.href = '#';\n", + " button.title = 'Stop Interaction';\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', function (_evt) {\n", + " fig.handle_close(fig, {});\n", + " });\n", + " button.addEventListener(\n", + " 'mouseover',\n", + " on_mouseover_closure('Stop Interaction')\n", + " );\n", + " buttongrp.appendChild(button);\n", + " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", + " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", + "};\n", + "\n", + "mpl.figure.prototype._remove_fig_handler = function (event) {\n", + " var fig = event.data.fig;\n", + " if (event.target !== this) {\n", + " // Ignore bubbled events from children.\n", + " return;\n", + " }\n", + " fig.close_ws(fig, {});\n", + "};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (el) {\n", + " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (el) {\n", + " // this is important to make the div 'focusable\n", + " el.setAttribute('tabindex', 0);\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " } else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager) {\n", + " manager = IPython.keyboard_manager;\n", + " }\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which === 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " fig.ondownload(fig, null);\n", + "};\n", + "\n", + "mpl.find_output_cell = function (html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i = 0; i < ncells; i++) {\n", + " var cell = cells[i];\n", + " if (cell.cell_type === 'code') {\n", + " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", + " var data = cell.output_area.outputs[j];\n", + " if (data.data) {\n", + " // IPython >= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] === html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "};\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel !== null) {\n", + " IPython.notebook.kernel.comm_manager.register_target(\n", + " 'matplotlib',\n", + " mpl.mpl_figure_comm\n", + " );\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cave.pimp_forward_selection()\n", + "cave.cave_ablation()" + ] + }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], + "source": [ + "cave.pimp_comparison_table()" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
-------------------- Single importance: ----------------------------------------
sequence_length71.3694 +/- 21.4898
delay11.5613 +/- 9.2271
-------------------- Pairwise importance: ----------------------------------------
sequence_length & delay17.0694 +/- 14.6953
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "/* global mpl */\n", + "window.mpl = {};\n", + "\n", + "mpl.get_websocket_type = function () {\n", + " if (typeof WebSocket !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof MozWebSocket !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert(\n", + " 'Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.'\n", + " );\n", + " }\n", + "};\n", + "\n", + "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = this.ws.binaryType !== undefined;\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById('mpl-warnings');\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent =\n", + " 'This browser does not support binary websocket messages. ' +\n", + " 'Performance may be slow.';\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = document.createElement('div');\n", + " this.root.setAttribute('style', 'display: inline-block');\n", + " this._root_extra_style(this.root);\n", + "\n", + " parent_element.appendChild(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message('supports_binary', { value: fig.supports_binary });\n", + " fig.send_message('send_image_mode', {});\n", + " if (fig.ratio !== 1) {\n", + " fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n", + " }\n", + " fig.send_message('refresh', {});\n", + " };\n", + "\n", + " this.imageObj.onload = function () {\n", + " if (fig.image_mode === 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function () {\n", + " fig.ws.close();\n", + " };\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "};\n", + "\n", + "mpl.figure.prototype._init_header = function () {\n", + " var titlebar = document.createElement('div');\n", + " titlebar.classList =\n", + " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", + " var titletext = document.createElement('div');\n", + " titletext.classList = 'ui-dialog-title';\n", + " titletext.setAttribute(\n", + " 'style',\n", + " 'width: 100%; text-align: center; padding: 3px;'\n", + " );\n", + " titlebar.appendChild(titletext);\n", + " this.root.appendChild(titlebar);\n", + " this.header = titletext;\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._init_canvas = function () {\n", + " var fig = this;\n", + "\n", + " var canvas_div = (this.canvas_div = document.createElement('div'));\n", + " canvas_div.setAttribute(\n", + " 'style',\n", + " 'border: 1px solid #ddd;' +\n", + " 'box-sizing: content-box;' +\n", + " 'clear: both;' +\n", + " 'min-height: 1px;' +\n", + " 'min-width: 1px;' +\n", + " 'outline: 0;' +\n", + " 'overflow: hidden;' +\n", + " 'position: relative;' +\n", + " 'resize: both;'\n", + " );\n", + "\n", + " function on_keyboard_event_closure(name) {\n", + " return function (event) {\n", + " return fig.key_event(event, name);\n", + " };\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'keydown',\n", + " on_keyboard_event_closure('key_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'keyup',\n", + " on_keyboard_event_closure('key_release')\n", + " );\n", + "\n", + " this._canvas_extra_style(canvas_div);\n", + " this.root.appendChild(canvas_div);\n", + "\n", + " var canvas = (this.canvas = document.createElement('canvas'));\n", + " canvas.classList.add('mpl-canvas');\n", + " canvas.setAttribute('style', 'box-sizing: content-box;');\n", + "\n", + " this.context = canvas.getContext('2d');\n", + "\n", + " var backingStore =\n", + " this.context.backingStorePixelRatio ||\n", + " this.context.webkitBackingStorePixelRatio ||\n", + " this.context.mozBackingStorePixelRatio ||\n", + " this.context.msBackingStorePixelRatio ||\n", + " this.context.oBackingStorePixelRatio ||\n", + " this.context.backingStorePixelRatio ||\n", + " 1;\n", + "\n", + " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", + " 'canvas'\n", + " ));\n", + " rubberband_canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n", + " );\n", + "\n", + " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", + " if (this.ResizeObserver === undefined) {\n", + " if (window.ResizeObserver !== undefined) {\n", + " this.ResizeObserver = window.ResizeObserver;\n", + " } else {\n", + " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", + " this.ResizeObserver = obs.ResizeObserver;\n", + " }\n", + " }\n", + "\n", + " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", + " var nentries = entries.length;\n", + " for (var i = 0; i < nentries; i++) {\n", + " var entry = entries[i];\n", + " var width, height;\n", + " if (entry.contentBoxSize) {\n", + " if (entry.contentBoxSize instanceof Array) {\n", + " // Chrome 84 implements new version of spec.\n", + " width = entry.contentBoxSize[0].inlineSize;\n", + " height = entry.contentBoxSize[0].blockSize;\n", + " } else {\n", + " // Firefox implements old version of spec.\n", + " width = entry.contentBoxSize.inlineSize;\n", + " height = entry.contentBoxSize.blockSize;\n", + " }\n", + " } else {\n", + " // Chrome <84 implements even older version of spec.\n", + " width = entry.contentRect.width;\n", + " height = entry.contentRect.height;\n", + " }\n", + "\n", + " // Keep the size of the canvas and rubber band canvas in sync with\n", + " // the canvas container.\n", + " if (entry.devicePixelContentBoxSize) {\n", + " // Chrome 84 implements new version of spec.\n", + " canvas.setAttribute(\n", + " 'width',\n", + " entry.devicePixelContentBoxSize[0].inlineSize\n", + " );\n", + " canvas.setAttribute(\n", + " 'height',\n", + " entry.devicePixelContentBoxSize[0].blockSize\n", + " );\n", + " } else {\n", + " canvas.setAttribute('width', width * fig.ratio);\n", + " canvas.setAttribute('height', height * fig.ratio);\n", + " }\n", + " canvas.setAttribute(\n", + " 'style',\n", + " 'width: ' + width + 'px; height: ' + height + 'px;'\n", + " );\n", + "\n", + " rubberband_canvas.setAttribute('width', width);\n", + " rubberband_canvas.setAttribute('height', height);\n", + "\n", + " // And update the size in Python. We ignore the initial 0/0 size\n", + " // that occurs as the element is placed into the DOM, which should\n", + " // otherwise not happen due to the minimum size styling.\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", + " fig.request_resize(width, height);\n", + " }\n", + " }\n", + " });\n", + " this.resizeObserverInstance.observe(canvas_div);\n", + "\n", + " function on_mouse_event_closure(name) {\n", + " return function (event) {\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " }\n", + "\n", + " rubberband_canvas.addEventListener(\n", + " 'mousedown',\n", + " on_mouse_event_closure('button_press')\n", + " );\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseup',\n", + " on_mouse_event_closure('button_release')\n", + " );\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband_canvas.addEventListener(\n", + " 'mousemove',\n", + " on_mouse_event_closure('motion_notify')\n", + " );\n", + "\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseenter',\n", + " on_mouse_event_closure('figure_enter')\n", + " );\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseleave',\n", + " on_mouse_event_closure('figure_leave')\n", + " );\n", + "\n", + " canvas_div.addEventListener('wheel', function (event) {\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " on_mouse_event_closure('scroll')(event);\n", + " });\n", + "\n", + " canvas_div.appendChild(canvas);\n", + " canvas_div.appendChild(rubberband_canvas);\n", + "\n", + " this.rubberband_context = rubberband_canvas.getContext('2d');\n", + " this.rubberband_context.strokeStyle = '#000000';\n", + "\n", + " this._resize_canvas = function (width, height, forward) {\n", + " if (forward) {\n", + " canvas_div.style.width = width + 'px';\n", + " canvas_div.style.height = height + 'px';\n", + " }\n", + " };\n", + "\n", + " // Disable right mouse context menu.\n", + " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n", + " event.preventDefault();\n", + " return false;\n", + " });\n", + "\n", + " function set_focus() {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'mpl-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " continue;\n", + " }\n", + "\n", + " var button = (fig.buttons[name] = document.createElement('button'));\n", + " button.classList = 'mpl-widget';\n", + " button.setAttribute('role', 'button');\n", + " button.setAttribute('aria-disabled', 'false');\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + "\n", + " var icon_img = document.createElement('img');\n", + " icon_img.src = '_images/' + image + '.png';\n", + " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", + " icon_img.alt = tooltip;\n", + " button.appendChild(icon_img);\n", + "\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " var fmt_picker = document.createElement('select');\n", + " fmt_picker.classList = 'mpl-widget';\n", + " toolbar.appendChild(fmt_picker);\n", + " this.format_dropdown = fmt_picker;\n", + "\n", + " for (var ind in mpl.extensions) {\n", + " var fmt = mpl.extensions[ind];\n", + " var option = document.createElement('option');\n", + " option.selected = fmt === mpl.default_extension;\n", + " option.innerHTML = fmt;\n", + " fmt_picker.appendChild(option);\n", + " }\n", + "\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "};\n", + "\n", + "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", + " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", + " // which will in turn request a refresh of the image.\n", + " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", + "};\n", + "\n", + "mpl.figure.prototype.send_message = function (type, properties) {\n", + " properties['type'] = type;\n", + " properties['figure_id'] = this.id;\n", + " this.ws.send(JSON.stringify(properties));\n", + "};\n", + "\n", + "mpl.figure.prototype.send_draw_message = function () {\n", + " if (!this.waiting) {\n", + " this.waiting = true;\n", + " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " var format_dropdown = fig.format_dropdown;\n", + " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", + " fig.ondownload(fig, format);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", + " var size = msg['size'];\n", + " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", + " fig._resize_canvas(size[0], size[1], msg['forward']);\n", + " fig.send_message('refresh', {});\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", + " var x0 = msg['x0'] / fig.ratio;\n", + " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", + " var x1 = msg['x1'] / fig.ratio;\n", + " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", + " x0 = Math.floor(x0) + 0.5;\n", + " y0 = Math.floor(y0) + 0.5;\n", + " x1 = Math.floor(x1) + 0.5;\n", + " y1 = Math.floor(y1) + 0.5;\n", + " var min_x = Math.min(x0, x1);\n", + " var min_y = Math.min(y0, y1);\n", + " var width = Math.abs(x1 - x0);\n", + " var height = Math.abs(y1 - y0);\n", + "\n", + " fig.rubberband_context.clearRect(\n", + " 0,\n", + " 0,\n", + " fig.canvas.width / fig.ratio,\n", + " fig.canvas.height / fig.ratio\n", + " );\n", + "\n", + " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", + " // Updates the figure title.\n", + " fig.header.textContent = msg['label'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", + " var cursor = msg['cursor'];\n", + " switch (cursor) {\n", + " case 0:\n", + " cursor = 'pointer';\n", + " break;\n", + " case 1:\n", + " cursor = 'default';\n", + " break;\n", + " case 2:\n", + " cursor = 'crosshair';\n", + " break;\n", + " case 3:\n", + " cursor = 'move';\n", + " break;\n", + " }\n", + " fig.rubberband_canvas.style.cursor = cursor;\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_message = function (fig, msg) {\n", + " fig.message.textContent = msg['message'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", + " // Request the server to send over a new figure.\n", + " fig.send_draw_message();\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", + " fig.image_mode = msg['mode'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", + " for (var key in msg) {\n", + " if (!(key in fig.buttons)) {\n", + " continue;\n", + " }\n", + " fig.buttons[key].disabled = !msg[key];\n", + " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", + " if (msg['mode'] === 'PAN') {\n", + " fig.buttons['Pan'].classList.add('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " } else if (msg['mode'] === 'ZOOM') {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.add('active');\n", + " } else {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Called whenever the canvas gets updated.\n", + " this.send_message('ack', {});\n", + "};\n", + "\n", + "// A function to construct a web socket function for onmessage handling.\n", + "// Called in the figure constructor.\n", + "mpl.figure.prototype._make_on_message_function = function (fig) {\n", + " return function socket_on_message(evt) {\n", + " if (evt.data instanceof Blob) {\n", + " /* FIXME: We get \"Resource interpreted as Image but\n", + " * transferred with MIME type text/plain:\" errors on\n", + " * Chrome. But how to set the MIME type? It doesn't seem\n", + " * to be part of the websocket stream */\n", + " evt.data.type = 'image/png';\n", + "\n", + " /* Free the memory for the previous frames */\n", + " if (fig.imageObj.src) {\n", + " (window.URL || window.webkitURL).revokeObjectURL(\n", + " fig.imageObj.src\n", + " );\n", + " }\n", + "\n", + " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", + " evt.data\n", + " );\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " } else if (\n", + " typeof evt.data === 'string' &&\n", + " evt.data.slice(0, 21) === 'data:image/png;base64'\n", + " ) {\n", + " fig.imageObj.src = evt.data;\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " }\n", + "\n", + " var msg = JSON.parse(evt.data);\n", + " var msg_type = msg['type'];\n", + "\n", + " // Call the \"handle_{type}\" callback, which takes\n", + " // the figure and JSON message as its only arguments.\n", + " try {\n", + " var callback = fig['handle_' + msg_type];\n", + " } catch (e) {\n", + " console.log(\n", + " \"No handler for the '\" + msg_type + \"' message type: \",\n", + " msg\n", + " );\n", + " return;\n", + " }\n", + "\n", + " if (callback) {\n", + " try {\n", + " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", + " callback(fig, msg);\n", + " } catch (e) {\n", + " console.log(\n", + " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", + " e,\n", + " e.stack,\n", + " msg\n", + " );\n", + " }\n", + " }\n", + " };\n", + "};\n", + "\n", + "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", + "mpl.findpos = function (e) {\n", + " //this section is from http://www.quirksmode.org/js/events_properties.html\n", + " var targ;\n", + " if (!e) {\n", + " e = window.event;\n", + " }\n", + " if (e.target) {\n", + " targ = e.target;\n", + " } else if (e.srcElement) {\n", + " targ = e.srcElement;\n", + " }\n", + " if (targ.nodeType === 3) {\n", + " // defeat Safari bug\n", + " targ = targ.parentNode;\n", + " }\n", + "\n", + " // pageX,Y are the mouse positions relative to the document\n", + " var boundingRect = targ.getBoundingClientRect();\n", + " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n", + " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n", + "\n", + " return { x: x, y: y };\n", + "};\n", + "\n", + "/*\n", + " * return a copy of an object with only non-object keys\n", + " * we need this to avoid circular references\n", + " * http://stackoverflow.com/a/24161582/3208463\n", + " */\n", + "function simpleKeys(original) {\n", + " return Object.keys(original).reduce(function (obj, key) {\n", + " if (typeof original[key] !== 'object') {\n", + " obj[key] = original[key];\n", + " }\n", + " return obj;\n", + " }, {});\n", + "}\n", + "\n", + "mpl.figure.prototype.mouse_event = function (event, name) {\n", + " var canvas_pos = mpl.findpos(event);\n", + "\n", + " if (name === 'button_press') {\n", + " this.canvas.focus();\n", + " this.canvas_div.focus();\n", + " }\n", + "\n", + " var x = canvas_pos.x * this.ratio;\n", + " var y = canvas_pos.y * this.ratio;\n", + "\n", + " this.send_message(name, {\n", + " x: x,\n", + " y: y,\n", + " button: event.button,\n", + " step: event.step,\n", + " guiEvent: simpleKeys(event),\n", + " });\n", + "\n", + " /* This prevents the web browser from automatically changing to\n", + " * the text insertion cursor when the button is pressed. We want\n", + " * to control all of the cursor setting manually through the\n", + " * 'cursor' event from matplotlib */\n", + " event.preventDefault();\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", + " // Handle any extra behaviour associated with a key event\n", + "};\n", + "\n", + "mpl.figure.prototype.key_event = function (event, name) {\n", + " // Prevent repeat events\n", + " if (name === 'key_press') {\n", + " if (event.which === this._key) {\n", + " return;\n", + " } else {\n", + " this._key = event.which;\n", + " }\n", + " }\n", + " if (name === 'key_release') {\n", + " this._key = null;\n", + " }\n", + "\n", + " var value = '';\n", + " if (event.ctrlKey && event.which !== 17) {\n", + " value += 'ctrl+';\n", + " }\n", + " if (event.altKey && event.which !== 18) {\n", + " value += 'alt+';\n", + " }\n", + " if (event.shiftKey && event.which !== 16) {\n", + " value += 'shift+';\n", + " }\n", + "\n", + " value += 'k';\n", + " value += event.which.toString();\n", + "\n", + " this._key_event_extra(event, name);\n", + "\n", + " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", + " if (name === 'download') {\n", + " this.handle_save(this, null);\n", + " } else {\n", + " this.send_message('toolbar_button', { name: name });\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", + " this.message.textContent = tooltip;\n", + "};\n", + "\n", + "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", + "// prettier-ignore\n", + "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", + "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", + "\n", + "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", + "\n", + "mpl.default_extension = \"png\";/* global mpl */\n", + "\n", + "var comm_websocket_adapter = function (comm) {\n", + " // Create a \"websocket\"-like object which calls the given IPython comm\n", + " // object with the appropriate methods. Currently this is a non binary\n", + " // socket, so there is still some room for performance tuning.\n", + " var ws = {};\n", + "\n", + " ws.close = function () {\n", + " comm.close();\n", + " };\n", + " ws.send = function (m) {\n", + " //console.log('sending', m);\n", + " comm.send(m);\n", + " };\n", + " // Register the callback with on_msg.\n", + " comm.on_msg(function (msg) {\n", + " //console.log('receiving', msg['content']['data'], msg);\n", + " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", + " ws.onmessage(msg['content']['data']);\n", + " });\n", + " return ws;\n", + "};\n", + "\n", + "mpl.mpl_figure_comm = function (comm, msg) {\n", + " // This is the function which gets called when the mpl process\n", + " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", + "\n", + " var id = msg.content.data.id;\n", + " // Get hold of the div created by the display call when the Comm\n", + " // socket was opened in Python.\n", + " var element = document.getElementById(id);\n", + " var ws_proxy = comm_websocket_adapter(comm);\n", + "\n", + " function ondownload(figure, _format) {\n", + " window.open(figure.canvas.toDataURL());\n", + " }\n", + "\n", + " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", + "\n", + " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", + " // web socket which is closed, not our websocket->open comm proxy.\n", + " ws_proxy.onopen();\n", + "\n", + " fig.parent_element = element;\n", + " fig.cell_info = mpl.find_output_cell(\"
\");\n", + " if (!fig.cell_info) {\n", + " console.error('Failed to find cell for figure', id, fig);\n", + " return;\n", + " }\n", + " fig.cell_info[0].output_area.element.on(\n", + " 'cleared',\n", + " { fig: fig },\n", + " fig._remove_fig_handler\n", + " );\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_close = function (fig, msg) {\n", + " var width = fig.canvas.width / fig.ratio;\n", + " fig.cell_info[0].output_area.element.off(\n", + " 'cleared',\n", + " fig._remove_fig_handler\n", + " );\n", + " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", + "\n", + " // Update the output cell to use the data from the current canvas.\n", + " fig.push_to_output();\n", + " var dataURL = fig.canvas.toDataURL();\n", + " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", + " // the notebook keyboard shortcuts fail.\n", + " IPython.keyboard_manager.enable();\n", + " fig.parent_element.innerHTML =\n", + " '';\n", + " fig.close_ws(fig, msg);\n", + "};\n", + "\n", + "mpl.figure.prototype.close_ws = function (fig, msg) {\n", + " fig.send_message('closing', msg);\n", + " // fig.ws.close()\n", + "};\n", + "\n", + "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", + " // Turn the data on the canvas into data in the output cell.\n", + " var width = this.canvas.width / this.ratio;\n", + " var dataURL = this.canvas.toDataURL();\n", + " this.cell_info[1]['text/html'] =\n", + " '';\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Tell IPython that the notebook contents must change.\n", + " IPython.notebook.set_dirty(true);\n", + " this.send_message('ack', {});\n", + " var fig = this;\n", + " // Wait a second, then push the new image to the DOM so\n", + " // that it is saved nicely (might be nice to debounce this).\n", + " setTimeout(function () {\n", + " fig.push_to_output();\n", + " }, 1000);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'btn-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " var button;\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " continue;\n", + " }\n", + "\n", + " button = fig.buttons[name] = document.createElement('button');\n", + " button.classList = 'btn btn-default';\n", + " button.href = '#';\n", + " button.title = name;\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message pull-right';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = document.createElement('div');\n", + " buttongrp.classList = 'btn-group inline pull-right';\n", + " button = document.createElement('button');\n", + " button.classList = 'btn btn-mini btn-primary';\n", + " button.href = '#';\n", + " button.title = 'Stop Interaction';\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', function (_evt) {\n", + " fig.handle_close(fig, {});\n", + " });\n", + " button.addEventListener(\n", + " 'mouseover',\n", + " on_mouseover_closure('Stop Interaction')\n", + " );\n", + " buttongrp.appendChild(button);\n", + " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", + " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", + "};\n", + "\n", + "mpl.figure.prototype._remove_fig_handler = function (event) {\n", + " var fig = event.data.fig;\n", + " if (event.target !== this) {\n", + " // Ignore bubbled events from children.\n", + " return;\n", + " }\n", + " fig.close_ws(fig, {});\n", + "};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (el) {\n", + " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (el) {\n", + " // this is important to make the div 'focusable\n", + " el.setAttribute('tabindex', 0);\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " } else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager) {\n", + " manager = IPython.keyboard_manager;\n", + " }\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which === 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " fig.ondownload(fig, null);\n", + "};\n", + "\n", + "mpl.find_output_cell = function (html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i = 0; i < ncells; i++) {\n", + " var cell = cells[i];\n", + " if (cell.cell_type === 'code') {\n", + " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", + " var data = cell.output_area.outputs[j];\n", + " if (data.data) {\n", + " // IPython >= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] === html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "};\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel !== null) {\n", + " IPython.notebook.kernel.comm_manager.register_target(\n", + " 'matplotlib',\n", + " mpl.mpl_figure_comm\n", + " );\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "/* global mpl */\n", + "window.mpl = {};\n", + "\n", + "mpl.get_websocket_type = function () {\n", + " if (typeof WebSocket !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof MozWebSocket !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert(\n", + " 'Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.'\n", + " );\n", + " }\n", + "};\n", + "\n", + "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = this.ws.binaryType !== undefined;\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById('mpl-warnings');\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent =\n", + " 'This browser does not support binary websocket messages. ' +\n", + " 'Performance may be slow.';\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = document.createElement('div');\n", + " this.root.setAttribute('style', 'display: inline-block');\n", + " this._root_extra_style(this.root);\n", + "\n", + " parent_element.appendChild(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message('supports_binary', { value: fig.supports_binary });\n", + " fig.send_message('send_image_mode', {});\n", + " if (fig.ratio !== 1) {\n", + " fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n", + " }\n", + " fig.send_message('refresh', {});\n", + " };\n", + "\n", + " this.imageObj.onload = function () {\n", + " if (fig.image_mode === 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function () {\n", + " fig.ws.close();\n", + " };\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "};\n", + "\n", + "mpl.figure.prototype._init_header = function () {\n", + " var titlebar = document.createElement('div');\n", + " titlebar.classList =\n", + " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", + " var titletext = document.createElement('div');\n", + " titletext.classList = 'ui-dialog-title';\n", + " titletext.setAttribute(\n", + " 'style',\n", + " 'width: 100%; text-align: center; padding: 3px;'\n", + " );\n", + " titlebar.appendChild(titletext);\n", + " this.root.appendChild(titlebar);\n", + " this.header = titletext;\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._init_canvas = function () {\n", + " var fig = this;\n", + "\n", + " var canvas_div = (this.canvas_div = document.createElement('div'));\n", + " canvas_div.setAttribute(\n", + " 'style',\n", + " 'border: 1px solid #ddd;' +\n", + " 'box-sizing: content-box;' +\n", + " 'clear: both;' +\n", + " 'min-height: 1px;' +\n", + " 'min-width: 1px;' +\n", + " 'outline: 0;' +\n", + " 'overflow: hidden;' +\n", + " 'position: relative;' +\n", + " 'resize: both;'\n", + " );\n", + "\n", + " function on_keyboard_event_closure(name) {\n", + " return function (event) {\n", + " return fig.key_event(event, name);\n", + " };\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'keydown',\n", + " on_keyboard_event_closure('key_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'keyup',\n", + " on_keyboard_event_closure('key_release')\n", + " );\n", + "\n", + " this._canvas_extra_style(canvas_div);\n", + " this.root.appendChild(canvas_div);\n", + "\n", + " var canvas = (this.canvas = document.createElement('canvas'));\n", + " canvas.classList.add('mpl-canvas');\n", + " canvas.setAttribute('style', 'box-sizing: content-box;');\n", + "\n", + " this.context = canvas.getContext('2d');\n", + "\n", + " var backingStore =\n", + " this.context.backingStorePixelRatio ||\n", + " this.context.webkitBackingStorePixelRatio ||\n", + " this.context.mozBackingStorePixelRatio ||\n", + " this.context.msBackingStorePixelRatio ||\n", + " this.context.oBackingStorePixelRatio ||\n", + " this.context.backingStorePixelRatio ||\n", + " 1;\n", + "\n", + " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", + " 'canvas'\n", + " ));\n", + " rubberband_canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n", + " );\n", + "\n", + " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", + " if (this.ResizeObserver === undefined) {\n", + " if (window.ResizeObserver !== undefined) {\n", + " this.ResizeObserver = window.ResizeObserver;\n", + " } else {\n", + " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", + " this.ResizeObserver = obs.ResizeObserver;\n", + " }\n", + " }\n", + "\n", + " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", + " var nentries = entries.length;\n", + " for (var i = 0; i < nentries; i++) {\n", + " var entry = entries[i];\n", + " var width, height;\n", + " if (entry.contentBoxSize) {\n", + " if (entry.contentBoxSize instanceof Array) {\n", + " // Chrome 84 implements new version of spec.\n", + " width = entry.contentBoxSize[0].inlineSize;\n", + " height = entry.contentBoxSize[0].blockSize;\n", + " } else {\n", + " // Firefox implements old version of spec.\n", + " width = entry.contentBoxSize.inlineSize;\n", + " height = entry.contentBoxSize.blockSize;\n", + " }\n", + " } else {\n", + " // Chrome <84 implements even older version of spec.\n", + " width = entry.contentRect.width;\n", + " height = entry.contentRect.height;\n", + " }\n", + "\n", + " // Keep the size of the canvas and rubber band canvas in sync with\n", + " // the canvas container.\n", + " if (entry.devicePixelContentBoxSize) {\n", + " // Chrome 84 implements new version of spec.\n", + " canvas.setAttribute(\n", + " 'width',\n", + " entry.devicePixelContentBoxSize[0].inlineSize\n", + " );\n", + " canvas.setAttribute(\n", + " 'height',\n", + " entry.devicePixelContentBoxSize[0].blockSize\n", + " );\n", + " } else {\n", + " canvas.setAttribute('width', width * fig.ratio);\n", + " canvas.setAttribute('height', height * fig.ratio);\n", + " }\n", + " canvas.setAttribute(\n", + " 'style',\n", + " 'width: ' + width + 'px; height: ' + height + 'px;'\n", + " );\n", + "\n", + " rubberband_canvas.setAttribute('width', width);\n", + " rubberband_canvas.setAttribute('height', height);\n", + "\n", + " // And update the size in Python. We ignore the initial 0/0 size\n", + " // that occurs as the element is placed into the DOM, which should\n", + " // otherwise not happen due to the minimum size styling.\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", + " fig.request_resize(width, height);\n", + " }\n", + " }\n", + " });\n", + " this.resizeObserverInstance.observe(canvas_div);\n", + "\n", + " function on_mouse_event_closure(name) {\n", + " return function (event) {\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " }\n", + "\n", + " rubberband_canvas.addEventListener(\n", + " 'mousedown',\n", + " on_mouse_event_closure('button_press')\n", + " );\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseup',\n", + " on_mouse_event_closure('button_release')\n", + " );\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband_canvas.addEventListener(\n", + " 'mousemove',\n", + " on_mouse_event_closure('motion_notify')\n", + " );\n", + "\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseenter',\n", + " on_mouse_event_closure('figure_enter')\n", + " );\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseleave',\n", + " on_mouse_event_closure('figure_leave')\n", + " );\n", + "\n", + " canvas_div.addEventListener('wheel', function (event) {\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " on_mouse_event_closure('scroll')(event);\n", + " });\n", + "\n", + " canvas_div.appendChild(canvas);\n", + " canvas_div.appendChild(rubberband_canvas);\n", + "\n", + " this.rubberband_context = rubberband_canvas.getContext('2d');\n", + " this.rubberband_context.strokeStyle = '#000000';\n", + "\n", + " this._resize_canvas = function (width, height, forward) {\n", + " if (forward) {\n", + " canvas_div.style.width = width + 'px';\n", + " canvas_div.style.height = height + 'px';\n", + " }\n", + " };\n", + "\n", + " // Disable right mouse context menu.\n", + " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n", + " event.preventDefault();\n", + " return false;\n", + " });\n", + "\n", + " function set_focus() {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'mpl-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " continue;\n", + " }\n", + "\n", + " var button = (fig.buttons[name] = document.createElement('button'));\n", + " button.classList = 'mpl-widget';\n", + " button.setAttribute('role', 'button');\n", + " button.setAttribute('aria-disabled', 'false');\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + "\n", + " var icon_img = document.createElement('img');\n", + " icon_img.src = '_images/' + image + '.png';\n", + " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", + " icon_img.alt = tooltip;\n", + " button.appendChild(icon_img);\n", + "\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " var fmt_picker = document.createElement('select');\n", + " fmt_picker.classList = 'mpl-widget';\n", + " toolbar.appendChild(fmt_picker);\n", + " this.format_dropdown = fmt_picker;\n", + "\n", + " for (var ind in mpl.extensions) {\n", + " var fmt = mpl.extensions[ind];\n", + " var option = document.createElement('option');\n", + " option.selected = fmt === mpl.default_extension;\n", + " option.innerHTML = fmt;\n", + " fmt_picker.appendChild(option);\n", + " }\n", + "\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "};\n", + "\n", + "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", + " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", + " // which will in turn request a refresh of the image.\n", + " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", + "};\n", + "\n", + "mpl.figure.prototype.send_message = function (type, properties) {\n", + " properties['type'] = type;\n", + " properties['figure_id'] = this.id;\n", + " this.ws.send(JSON.stringify(properties));\n", + "};\n", + "\n", + "mpl.figure.prototype.send_draw_message = function () {\n", + " if (!this.waiting) {\n", + " this.waiting = true;\n", + " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " var format_dropdown = fig.format_dropdown;\n", + " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", + " fig.ondownload(fig, format);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", + " var size = msg['size'];\n", + " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", + " fig._resize_canvas(size[0], size[1], msg['forward']);\n", + " fig.send_message('refresh', {});\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", + " var x0 = msg['x0'] / fig.ratio;\n", + " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", + " var x1 = msg['x1'] / fig.ratio;\n", + " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", + " x0 = Math.floor(x0) + 0.5;\n", + " y0 = Math.floor(y0) + 0.5;\n", + " x1 = Math.floor(x1) + 0.5;\n", + " y1 = Math.floor(y1) + 0.5;\n", + " var min_x = Math.min(x0, x1);\n", + " var min_y = Math.min(y0, y1);\n", + " var width = Math.abs(x1 - x0);\n", + " var height = Math.abs(y1 - y0);\n", + "\n", + " fig.rubberband_context.clearRect(\n", + " 0,\n", + " 0,\n", + " fig.canvas.width / fig.ratio,\n", + " fig.canvas.height / fig.ratio\n", + " );\n", + "\n", + " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", + " // Updates the figure title.\n", + " fig.header.textContent = msg['label'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", + " var cursor = msg['cursor'];\n", + " switch (cursor) {\n", + " case 0:\n", + " cursor = 'pointer';\n", + " break;\n", + " case 1:\n", + " cursor = 'default';\n", + " break;\n", + " case 2:\n", + " cursor = 'crosshair';\n", + " break;\n", + " case 3:\n", + " cursor = 'move';\n", + " break;\n", + " }\n", + " fig.rubberband_canvas.style.cursor = cursor;\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_message = function (fig, msg) {\n", + " fig.message.textContent = msg['message'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", + " // Request the server to send over a new figure.\n", + " fig.send_draw_message();\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", + " fig.image_mode = msg['mode'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", + " for (var key in msg) {\n", + " if (!(key in fig.buttons)) {\n", + " continue;\n", + " }\n", + " fig.buttons[key].disabled = !msg[key];\n", + " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", + " if (msg['mode'] === 'PAN') {\n", + " fig.buttons['Pan'].classList.add('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " } else if (msg['mode'] === 'ZOOM') {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.add('active');\n", + " } else {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Called whenever the canvas gets updated.\n", + " this.send_message('ack', {});\n", + "};\n", + "\n", + "// A function to construct a web socket function for onmessage handling.\n", + "// Called in the figure constructor.\n", + "mpl.figure.prototype._make_on_message_function = function (fig) {\n", + " return function socket_on_message(evt) {\n", + " if (evt.data instanceof Blob) {\n", + " /* FIXME: We get \"Resource interpreted as Image but\n", + " * transferred with MIME type text/plain:\" errors on\n", + " * Chrome. But how to set the MIME type? It doesn't seem\n", + " * to be part of the websocket stream */\n", + " evt.data.type = 'image/png';\n", + "\n", + " /* Free the memory for the previous frames */\n", + " if (fig.imageObj.src) {\n", + " (window.URL || window.webkitURL).revokeObjectURL(\n", + " fig.imageObj.src\n", + " );\n", + " }\n", + "\n", + " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", + " evt.data\n", + " );\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " } else if (\n", + " typeof evt.data === 'string' &&\n", + " evt.data.slice(0, 21) === 'data:image/png;base64'\n", + " ) {\n", + " fig.imageObj.src = evt.data;\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " }\n", + "\n", + " var msg = JSON.parse(evt.data);\n", + " var msg_type = msg['type'];\n", + "\n", + " // Call the \"handle_{type}\" callback, which takes\n", + " // the figure and JSON message as its only arguments.\n", + " try {\n", + " var callback = fig['handle_' + msg_type];\n", + " } catch (e) {\n", + " console.log(\n", + " \"No handler for the '\" + msg_type + \"' message type: \",\n", + " msg\n", + " );\n", + " return;\n", + " }\n", + "\n", + " if (callback) {\n", + " try {\n", + " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", + " callback(fig, msg);\n", + " } catch (e) {\n", + " console.log(\n", + " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", + " e,\n", + " e.stack,\n", + " msg\n", + " );\n", + " }\n", + " }\n", + " };\n", + "};\n", + "\n", + "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", + "mpl.findpos = function (e) {\n", + " //this section is from http://www.quirksmode.org/js/events_properties.html\n", + " var targ;\n", + " if (!e) {\n", + " e = window.event;\n", + " }\n", + " if (e.target) {\n", + " targ = e.target;\n", + " } else if (e.srcElement) {\n", + " targ = e.srcElement;\n", + " }\n", + " if (targ.nodeType === 3) {\n", + " // defeat Safari bug\n", + " targ = targ.parentNode;\n", + " }\n", + "\n", + " // pageX,Y are the mouse positions relative to the document\n", + " var boundingRect = targ.getBoundingClientRect();\n", + " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n", + " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n", + "\n", + " return { x: x, y: y };\n", + "};\n", + "\n", + "/*\n", + " * return a copy of an object with only non-object keys\n", + " * we need this to avoid circular references\n", + " * http://stackoverflow.com/a/24161582/3208463\n", + " */\n", + "function simpleKeys(original) {\n", + " return Object.keys(original).reduce(function (obj, key) {\n", + " if (typeof original[key] !== 'object') {\n", + " obj[key] = original[key];\n", + " }\n", + " return obj;\n", + " }, {});\n", + "}\n", + "\n", + "mpl.figure.prototype.mouse_event = function (event, name) {\n", + " var canvas_pos = mpl.findpos(event);\n", + "\n", + " if (name === 'button_press') {\n", + " this.canvas.focus();\n", + " this.canvas_div.focus();\n", + " }\n", + "\n", + " var x = canvas_pos.x * this.ratio;\n", + " var y = canvas_pos.y * this.ratio;\n", + "\n", + " this.send_message(name, {\n", + " x: x,\n", + " y: y,\n", + " button: event.button,\n", + " step: event.step,\n", + " guiEvent: simpleKeys(event),\n", + " });\n", + "\n", + " /* This prevents the web browser from automatically changing to\n", + " * the text insertion cursor when the button is pressed. We want\n", + " * to control all of the cursor setting manually through the\n", + " * 'cursor' event from matplotlib */\n", + " event.preventDefault();\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", + " // Handle any extra behaviour associated with a key event\n", + "};\n", + "\n", + "mpl.figure.prototype.key_event = function (event, name) {\n", + " // Prevent repeat events\n", + " if (name === 'key_press') {\n", + " if (event.which === this._key) {\n", + " return;\n", + " } else {\n", + " this._key = event.which;\n", + " }\n", + " }\n", + " if (name === 'key_release') {\n", + " this._key = null;\n", + " }\n", + "\n", + " var value = '';\n", + " if (event.ctrlKey && event.which !== 17) {\n", + " value += 'ctrl+';\n", + " }\n", + " if (event.altKey && event.which !== 18) {\n", + " value += 'alt+';\n", + " }\n", + " if (event.shiftKey && event.which !== 16) {\n", + " value += 'shift+';\n", + " }\n", + "\n", + " value += 'k';\n", + " value += event.which.toString();\n", + "\n", + " this._key_event_extra(event, name);\n", + "\n", + " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", + " if (name === 'download') {\n", + " this.handle_save(this, null);\n", + " } else {\n", + " this.send_message('toolbar_button', { name: name });\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", + " this.message.textContent = tooltip;\n", + "};\n", + "\n", + "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", + "// prettier-ignore\n", + "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", + "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", + "\n", + "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", + "\n", + "mpl.default_extension = \"png\";/* global mpl */\n", + "\n", + "var comm_websocket_adapter = function (comm) {\n", + " // Create a \"websocket\"-like object which calls the given IPython comm\n", + " // object with the appropriate methods. Currently this is a non binary\n", + " // socket, so there is still some room for performance tuning.\n", + " var ws = {};\n", + "\n", + " ws.close = function () {\n", + " comm.close();\n", + " };\n", + " ws.send = function (m) {\n", + " //console.log('sending', m);\n", + " comm.send(m);\n", + " };\n", + " // Register the callback with on_msg.\n", + " comm.on_msg(function (msg) {\n", + " //console.log('receiving', msg['content']['data'], msg);\n", + " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", + " ws.onmessage(msg['content']['data']);\n", + " });\n", + " return ws;\n", + "};\n", + "\n", + "mpl.mpl_figure_comm = function (comm, msg) {\n", + " // This is the function which gets called when the mpl process\n", + " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", + "\n", + " var id = msg.content.data.id;\n", + " // Get hold of the div created by the display call when the Comm\n", + " // socket was opened in Python.\n", + " var element = document.getElementById(id);\n", + " var ws_proxy = comm_websocket_adapter(comm);\n", + "\n", + " function ondownload(figure, _format) {\n", + " window.open(figure.canvas.toDataURL());\n", + " }\n", + "\n", + " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", + "\n", + " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", + " // web socket which is closed, not our websocket->open comm proxy.\n", + " ws_proxy.onopen();\n", + "\n", + " fig.parent_element = element;\n", + " fig.cell_info = mpl.find_output_cell(\"
\");\n", + " if (!fig.cell_info) {\n", + " console.error('Failed to find cell for figure', id, fig);\n", + " return;\n", + " }\n", + " fig.cell_info[0].output_area.element.on(\n", + " 'cleared',\n", + " { fig: fig },\n", + " fig._remove_fig_handler\n", + " );\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_close = function (fig, msg) {\n", + " var width = fig.canvas.width / fig.ratio;\n", + " fig.cell_info[0].output_area.element.off(\n", + " 'cleared',\n", + " fig._remove_fig_handler\n", + " );\n", + " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", + "\n", + " // Update the output cell to use the data from the current canvas.\n", + " fig.push_to_output();\n", + " var dataURL = fig.canvas.toDataURL();\n", + " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", + " // the notebook keyboard shortcuts fail.\n", + " IPython.keyboard_manager.enable();\n", + " fig.parent_element.innerHTML =\n", + " '';\n", + " fig.close_ws(fig, msg);\n", + "};\n", + "\n", + "mpl.figure.prototype.close_ws = function (fig, msg) {\n", + " fig.send_message('closing', msg);\n", + " // fig.ws.close()\n", + "};\n", + "\n", + "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", + " // Turn the data on the canvas into data in the output cell.\n", + " var width = this.canvas.width / this.ratio;\n", + " var dataURL = this.canvas.toDataURL();\n", + " this.cell_info[1]['text/html'] =\n", + " '';\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Tell IPython that the notebook contents must change.\n", + " IPython.notebook.set_dirty(true);\n", + " this.send_message('ack', {});\n", + " var fig = this;\n", + " // Wait a second, then push the new image to the DOM so\n", + " // that it is saved nicely (might be nice to debounce this).\n", + " setTimeout(function () {\n", + " fig.push_to_output();\n", + " }, 1000);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'btn-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " var button;\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " continue;\n", + " }\n", + "\n", + " button = fig.buttons[name] = document.createElement('button');\n", + " button.classList = 'btn btn-default';\n", + " button.href = '#';\n", + " button.title = name;\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message pull-right';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = document.createElement('div');\n", + " buttongrp.classList = 'btn-group inline pull-right';\n", + " button = document.createElement('button');\n", + " button.classList = 'btn btn-mini btn-primary';\n", + " button.href = '#';\n", + " button.title = 'Stop Interaction';\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', function (_evt) {\n", + " fig.handle_close(fig, {});\n", + " });\n", + " button.addEventListener(\n", + " 'mouseover',\n", + " on_mouseover_closure('Stop Interaction')\n", + " );\n", + " buttongrp.appendChild(button);\n", + " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", + " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", + "};\n", + "\n", + "mpl.figure.prototype._remove_fig_handler = function (event) {\n", + " var fig = event.data.fig;\n", + " if (event.target !== this) {\n", + " // Ignore bubbled events from children.\n", + " return;\n", + " }\n", + " fig.close_ws(fig, {});\n", + "};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (el) {\n", + " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (el) {\n", + " // this is important to make the div 'focusable\n", + " el.setAttribute('tabindex', 0);\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " } else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager) {\n", + " manager = IPython.keyboard_manager;\n", + " }\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which === 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " fig.ondownload(fig, null);\n", + "};\n", + "\n", + "mpl.find_output_cell = function (html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i = 0; i < ncells; i++) {\n", + " var cell = cells[i];\n", + " if (cell.cell_type === 'code') {\n", + " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", + " var data = cell.output_area.outputs[j];\n", + " if (data.data) {\n", + " // IPython >= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] === html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "};\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel !== null) {\n", + " IPython.notebook.kernel.comm_manager.register_target(\n", + " 'matplotlib',\n", + " mpl.mpl_figure_comm\n", + " );\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "cave.cave_fanova()" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/pimp/evaluator/local_parameter_importance.py:402: UserWarning: Attempted to set non-positive top ylim on a log-scaled axis.\n", + "Invalid limit will be ignored.\n", + " ax1.set_ylim([min_y * 0.95, max_y])\n", + "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/pimp/evaluator/local_parameter_importance.py:402: UserWarning: Attempted to set non-positive top ylim on a log-scaled axis.\n", + "Invalid limit will be ignored.\n", + " ax1.set_ylim([min_y * 0.95, max_y])\n" + ] + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "/* global mpl */\n", + "window.mpl = {};\n", + "\n", + "mpl.get_websocket_type = function () {\n", + " if (typeof WebSocket !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof MozWebSocket !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert(\n", + " 'Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.'\n", + " );\n", + " }\n", + "};\n", + "\n", + "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = this.ws.binaryType !== undefined;\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById('mpl-warnings');\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent =\n", + " 'This browser does not support binary websocket messages. ' +\n", + " 'Performance may be slow.';\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = document.createElement('div');\n", + " this.root.setAttribute('style', 'display: inline-block');\n", + " this._root_extra_style(this.root);\n", + "\n", + " parent_element.appendChild(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message('supports_binary', { value: fig.supports_binary });\n", + " fig.send_message('send_image_mode', {});\n", + " if (fig.ratio !== 1) {\n", + " fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n", + " }\n", + " fig.send_message('refresh', {});\n", + " };\n", + "\n", + " this.imageObj.onload = function () {\n", + " if (fig.image_mode === 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function () {\n", + " fig.ws.close();\n", + " };\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "};\n", + "\n", + "mpl.figure.prototype._init_header = function () {\n", + " var titlebar = document.createElement('div');\n", + " titlebar.classList =\n", + " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", + " var titletext = document.createElement('div');\n", + " titletext.classList = 'ui-dialog-title';\n", + " titletext.setAttribute(\n", + " 'style',\n", + " 'width: 100%; text-align: center; padding: 3px;'\n", + " );\n", + " titlebar.appendChild(titletext);\n", + " this.root.appendChild(titlebar);\n", + " this.header = titletext;\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._init_canvas = function () {\n", + " var fig = this;\n", + "\n", + " var canvas_div = (this.canvas_div = document.createElement('div'));\n", + " canvas_div.setAttribute(\n", + " 'style',\n", + " 'border: 1px solid #ddd;' +\n", + " 'box-sizing: content-box;' +\n", + " 'clear: both;' +\n", + " 'min-height: 1px;' +\n", + " 'min-width: 1px;' +\n", + " 'outline: 0;' +\n", + " 'overflow: hidden;' +\n", + " 'position: relative;' +\n", + " 'resize: both;'\n", + " );\n", + "\n", + " function on_keyboard_event_closure(name) {\n", + " return function (event) {\n", + " return fig.key_event(event, name);\n", + " };\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'keydown',\n", + " on_keyboard_event_closure('key_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'keyup',\n", + " on_keyboard_event_closure('key_release')\n", + " );\n", + "\n", + " this._canvas_extra_style(canvas_div);\n", + " this.root.appendChild(canvas_div);\n", + "\n", + " var canvas = (this.canvas = document.createElement('canvas'));\n", + " canvas.classList.add('mpl-canvas');\n", + " canvas.setAttribute('style', 'box-sizing: content-box;');\n", + "\n", + " this.context = canvas.getContext('2d');\n", + "\n", + " var backingStore =\n", + " this.context.backingStorePixelRatio ||\n", + " this.context.webkitBackingStorePixelRatio ||\n", + " this.context.mozBackingStorePixelRatio ||\n", + " this.context.msBackingStorePixelRatio ||\n", + " this.context.oBackingStorePixelRatio ||\n", + " this.context.backingStorePixelRatio ||\n", + " 1;\n", + "\n", + " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", + " 'canvas'\n", + " ));\n", + " rubberband_canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n", + " );\n", + "\n", + " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", + " if (this.ResizeObserver === undefined) {\n", + " if (window.ResizeObserver !== undefined) {\n", + " this.ResizeObserver = window.ResizeObserver;\n", + " } else {\n", + " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", + " this.ResizeObserver = obs.ResizeObserver;\n", + " }\n", + " }\n", + "\n", + " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", + " var nentries = entries.length;\n", + " for (var i = 0; i < nentries; i++) {\n", + " var entry = entries[i];\n", + " var width, height;\n", + " if (entry.contentBoxSize) {\n", + " if (entry.contentBoxSize instanceof Array) {\n", + " // Chrome 84 implements new version of spec.\n", + " width = entry.contentBoxSize[0].inlineSize;\n", + " height = entry.contentBoxSize[0].blockSize;\n", + " } else {\n", + " // Firefox implements old version of spec.\n", + " width = entry.contentBoxSize.inlineSize;\n", + " height = entry.contentBoxSize.blockSize;\n", + " }\n", + " } else {\n", + " // Chrome <84 implements even older version of spec.\n", + " width = entry.contentRect.width;\n", + " height = entry.contentRect.height;\n", + " }\n", + "\n", + " // Keep the size of the canvas and rubber band canvas in sync with\n", + " // the canvas container.\n", + " if (entry.devicePixelContentBoxSize) {\n", + " // Chrome 84 implements new version of spec.\n", + " canvas.setAttribute(\n", + " 'width',\n", + " entry.devicePixelContentBoxSize[0].inlineSize\n", + " );\n", + " canvas.setAttribute(\n", + " 'height',\n", + " entry.devicePixelContentBoxSize[0].blockSize\n", + " );\n", + " } else {\n", + " canvas.setAttribute('width', width * fig.ratio);\n", + " canvas.setAttribute('height', height * fig.ratio);\n", + " }\n", + " canvas.setAttribute(\n", + " 'style',\n", + " 'width: ' + width + 'px; height: ' + height + 'px;'\n", + " );\n", + "\n", + " rubberband_canvas.setAttribute('width', width);\n", + " rubberband_canvas.setAttribute('height', height);\n", + "\n", + " // And update the size in Python. We ignore the initial 0/0 size\n", + " // that occurs as the element is placed into the DOM, which should\n", + " // otherwise not happen due to the minimum size styling.\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", + " fig.request_resize(width, height);\n", + " }\n", + " }\n", + " });\n", + " this.resizeObserverInstance.observe(canvas_div);\n", + "\n", + " function on_mouse_event_closure(name) {\n", + " return function (event) {\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " }\n", + "\n", + " rubberband_canvas.addEventListener(\n", + " 'mousedown',\n", + " on_mouse_event_closure('button_press')\n", + " );\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseup',\n", + " on_mouse_event_closure('button_release')\n", + " );\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband_canvas.addEventListener(\n", + " 'mousemove',\n", + " on_mouse_event_closure('motion_notify')\n", + " );\n", + "\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseenter',\n", + " on_mouse_event_closure('figure_enter')\n", + " );\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseleave',\n", + " on_mouse_event_closure('figure_leave')\n", + " );\n", + "\n", + " canvas_div.addEventListener('wheel', function (event) {\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " on_mouse_event_closure('scroll')(event);\n", + " });\n", + "\n", + " canvas_div.appendChild(canvas);\n", + " canvas_div.appendChild(rubberband_canvas);\n", + "\n", + " this.rubberband_context = rubberband_canvas.getContext('2d');\n", + " this.rubberband_context.strokeStyle = '#000000';\n", + "\n", + " this._resize_canvas = function (width, height, forward) {\n", + " if (forward) {\n", + " canvas_div.style.width = width + 'px';\n", + " canvas_div.style.height = height + 'px';\n", + " }\n", + " };\n", + "\n", + " // Disable right mouse context menu.\n", + " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n", + " event.preventDefault();\n", + " return false;\n", + " });\n", + "\n", + " function set_focus() {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'mpl-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " continue;\n", + " }\n", + "\n", + " var button = (fig.buttons[name] = document.createElement('button'));\n", + " button.classList = 'mpl-widget';\n", + " button.setAttribute('role', 'button');\n", + " button.setAttribute('aria-disabled', 'false');\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + "\n", + " var icon_img = document.createElement('img');\n", + " icon_img.src = '_images/' + image + '.png';\n", + " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", + " icon_img.alt = tooltip;\n", + " button.appendChild(icon_img);\n", + "\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " var fmt_picker = document.createElement('select');\n", + " fmt_picker.classList = 'mpl-widget';\n", + " toolbar.appendChild(fmt_picker);\n", + " this.format_dropdown = fmt_picker;\n", + "\n", + " for (var ind in mpl.extensions) {\n", + " var fmt = mpl.extensions[ind];\n", + " var option = document.createElement('option');\n", + " option.selected = fmt === mpl.default_extension;\n", + " option.innerHTML = fmt;\n", + " fmt_picker.appendChild(option);\n", + " }\n", + "\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "};\n", + "\n", + "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", + " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", + " // which will in turn request a refresh of the image.\n", + " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", + "};\n", + "\n", + "mpl.figure.prototype.send_message = function (type, properties) {\n", + " properties['type'] = type;\n", + " properties['figure_id'] = this.id;\n", + " this.ws.send(JSON.stringify(properties));\n", + "};\n", + "\n", + "mpl.figure.prototype.send_draw_message = function () {\n", + " if (!this.waiting) {\n", + " this.waiting = true;\n", + " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " var format_dropdown = fig.format_dropdown;\n", + " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", + " fig.ondownload(fig, format);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", + " var size = msg['size'];\n", + " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", + " fig._resize_canvas(size[0], size[1], msg['forward']);\n", + " fig.send_message('refresh', {});\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", + " var x0 = msg['x0'] / fig.ratio;\n", + " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", + " var x1 = msg['x1'] / fig.ratio;\n", + " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", + " x0 = Math.floor(x0) + 0.5;\n", + " y0 = Math.floor(y0) + 0.5;\n", + " x1 = Math.floor(x1) + 0.5;\n", + " y1 = Math.floor(y1) + 0.5;\n", + " var min_x = Math.min(x0, x1);\n", + " var min_y = Math.min(y0, y1);\n", + " var width = Math.abs(x1 - x0);\n", + " var height = Math.abs(y1 - y0);\n", + "\n", + " fig.rubberband_context.clearRect(\n", + " 0,\n", + " 0,\n", + " fig.canvas.width / fig.ratio,\n", + " fig.canvas.height / fig.ratio\n", + " );\n", + "\n", + " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", + " // Updates the figure title.\n", + " fig.header.textContent = msg['label'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", + " var cursor = msg['cursor'];\n", + " switch (cursor) {\n", + " case 0:\n", + " cursor = 'pointer';\n", + " break;\n", + " case 1:\n", + " cursor = 'default';\n", + " break;\n", + " case 2:\n", + " cursor = 'crosshair';\n", + " break;\n", + " case 3:\n", + " cursor = 'move';\n", + " break;\n", + " }\n", + " fig.rubberband_canvas.style.cursor = cursor;\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_message = function (fig, msg) {\n", + " fig.message.textContent = msg['message'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", + " // Request the server to send over a new figure.\n", + " fig.send_draw_message();\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", + " fig.image_mode = msg['mode'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", + " for (var key in msg) {\n", + " if (!(key in fig.buttons)) {\n", + " continue;\n", + " }\n", + " fig.buttons[key].disabled = !msg[key];\n", + " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", + " if (msg['mode'] === 'PAN') {\n", + " fig.buttons['Pan'].classList.add('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " } else if (msg['mode'] === 'ZOOM') {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.add('active');\n", + " } else {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Called whenever the canvas gets updated.\n", + " this.send_message('ack', {});\n", + "};\n", + "\n", + "// A function to construct a web socket function for onmessage handling.\n", + "// Called in the figure constructor.\n", + "mpl.figure.prototype._make_on_message_function = function (fig) {\n", + " return function socket_on_message(evt) {\n", + " if (evt.data instanceof Blob) {\n", + " /* FIXME: We get \"Resource interpreted as Image but\n", + " * transferred with MIME type text/plain:\" errors on\n", + " * Chrome. But how to set the MIME type? It doesn't seem\n", + " * to be part of the websocket stream */\n", + " evt.data.type = 'image/png';\n", + "\n", + " /* Free the memory for the previous frames */\n", + " if (fig.imageObj.src) {\n", + " (window.URL || window.webkitURL).revokeObjectURL(\n", + " fig.imageObj.src\n", + " );\n", + " }\n", + "\n", + " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", + " evt.data\n", + " );\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " } else if (\n", + " typeof evt.data === 'string' &&\n", + " evt.data.slice(0, 21) === 'data:image/png;base64'\n", + " ) {\n", + " fig.imageObj.src = evt.data;\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " }\n", + "\n", + " var msg = JSON.parse(evt.data);\n", + " var msg_type = msg['type'];\n", + "\n", + " // Call the \"handle_{type}\" callback, which takes\n", + " // the figure and JSON message as its only arguments.\n", + " try {\n", + " var callback = fig['handle_' + msg_type];\n", + " } catch (e) {\n", + " console.log(\n", + " \"No handler for the '\" + msg_type + \"' message type: \",\n", + " msg\n", + " );\n", + " return;\n", + " }\n", + "\n", + " if (callback) {\n", + " try {\n", + " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", + " callback(fig, msg);\n", + " } catch (e) {\n", + " console.log(\n", + " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", + " e,\n", + " e.stack,\n", + " msg\n", + " );\n", + " }\n", + " }\n", + " };\n", + "};\n", + "\n", + "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", + "mpl.findpos = function (e) {\n", + " //this section is from http://www.quirksmode.org/js/events_properties.html\n", + " var targ;\n", + " if (!e) {\n", + " e = window.event;\n", + " }\n", + " if (e.target) {\n", + " targ = e.target;\n", + " } else if (e.srcElement) {\n", + " targ = e.srcElement;\n", + " }\n", + " if (targ.nodeType === 3) {\n", + " // defeat Safari bug\n", + " targ = targ.parentNode;\n", + " }\n", + "\n", + " // pageX,Y are the mouse positions relative to the document\n", + " var boundingRect = targ.getBoundingClientRect();\n", + " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n", + " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n", + "\n", + " return { x: x, y: y };\n", + "};\n", + "\n", + "/*\n", + " * return a copy of an object with only non-object keys\n", + " * we need this to avoid circular references\n", + " * http://stackoverflow.com/a/24161582/3208463\n", + " */\n", + "function simpleKeys(original) {\n", + " return Object.keys(original).reduce(function (obj, key) {\n", + " if (typeof original[key] !== 'object') {\n", + " obj[key] = original[key];\n", + " }\n", + " return obj;\n", + " }, {});\n", + "}\n", + "\n", + "mpl.figure.prototype.mouse_event = function (event, name) {\n", + " var canvas_pos = mpl.findpos(event);\n", + "\n", + " if (name === 'button_press') {\n", + " this.canvas.focus();\n", + " this.canvas_div.focus();\n", + " }\n", + "\n", + " var x = canvas_pos.x * this.ratio;\n", + " var y = canvas_pos.y * this.ratio;\n", + "\n", + " this.send_message(name, {\n", + " x: x,\n", + " y: y,\n", + " button: event.button,\n", + " step: event.step,\n", + " guiEvent: simpleKeys(event),\n", + " });\n", + "\n", + " /* This prevents the web browser from automatically changing to\n", + " * the text insertion cursor when the button is pressed. We want\n", + " * to control all of the cursor setting manually through the\n", + " * 'cursor' event from matplotlib */\n", + " event.preventDefault();\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", + " // Handle any extra behaviour associated with a key event\n", + "};\n", + "\n", + "mpl.figure.prototype.key_event = function (event, name) {\n", + " // Prevent repeat events\n", + " if (name === 'key_press') {\n", + " if (event.which === this._key) {\n", + " return;\n", + " } else {\n", + " this._key = event.which;\n", + " }\n", + " }\n", + " if (name === 'key_release') {\n", + " this._key = null;\n", + " }\n", + "\n", + " var value = '';\n", + " if (event.ctrlKey && event.which !== 17) {\n", + " value += 'ctrl+';\n", + " }\n", + " if (event.altKey && event.which !== 18) {\n", + " value += 'alt+';\n", + " }\n", + " if (event.shiftKey && event.which !== 16) {\n", + " value += 'shift+';\n", + " }\n", + "\n", + " value += 'k';\n", + " value += event.which.toString();\n", + "\n", + " this._key_event_extra(event, name);\n", + "\n", + " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", + " if (name === 'download') {\n", + " this.handle_save(this, null);\n", + " } else {\n", + " this.send_message('toolbar_button', { name: name });\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", + " this.message.textContent = tooltip;\n", + "};\n", + "\n", + "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", + "// prettier-ignore\n", + "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", + "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", + "\n", + "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", + "\n", + "mpl.default_extension = \"png\";/* global mpl */\n", + "\n", + "var comm_websocket_adapter = function (comm) {\n", + " // Create a \"websocket\"-like object which calls the given IPython comm\n", + " // object with the appropriate methods. Currently this is a non binary\n", + " // socket, so there is still some room for performance tuning.\n", + " var ws = {};\n", + "\n", + " ws.close = function () {\n", + " comm.close();\n", + " };\n", + " ws.send = function (m) {\n", + " //console.log('sending', m);\n", + " comm.send(m);\n", + " };\n", + " // Register the callback with on_msg.\n", + " comm.on_msg(function (msg) {\n", + " //console.log('receiving', msg['content']['data'], msg);\n", + " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", + " ws.onmessage(msg['content']['data']);\n", + " });\n", + " return ws;\n", + "};\n", + "\n", + "mpl.mpl_figure_comm = function (comm, msg) {\n", + " // This is the function which gets called when the mpl process\n", + " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", + "\n", + " var id = msg.content.data.id;\n", + " // Get hold of the div created by the display call when the Comm\n", + " // socket was opened in Python.\n", + " var element = document.getElementById(id);\n", + " var ws_proxy = comm_websocket_adapter(comm);\n", + "\n", + " function ondownload(figure, _format) {\n", + " window.open(figure.canvas.toDataURL());\n", + " }\n", + "\n", + " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", + "\n", + " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", + " // web socket which is closed, not our websocket->open comm proxy.\n", + " ws_proxy.onopen();\n", + "\n", + " fig.parent_element = element;\n", + " fig.cell_info = mpl.find_output_cell(\"
\");\n", + " if (!fig.cell_info) {\n", + " console.error('Failed to find cell for figure', id, fig);\n", + " return;\n", + " }\n", + " fig.cell_info[0].output_area.element.on(\n", + " 'cleared',\n", + " { fig: fig },\n", + " fig._remove_fig_handler\n", + " );\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_close = function (fig, msg) {\n", + " var width = fig.canvas.width / fig.ratio;\n", + " fig.cell_info[0].output_area.element.off(\n", + " 'cleared',\n", + " fig._remove_fig_handler\n", + " );\n", + " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", + "\n", + " // Update the output cell to use the data from the current canvas.\n", + " fig.push_to_output();\n", + " var dataURL = fig.canvas.toDataURL();\n", + " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", + " // the notebook keyboard shortcuts fail.\n", + " IPython.keyboard_manager.enable();\n", + " fig.parent_element.innerHTML =\n", + " '';\n", + " fig.close_ws(fig, msg);\n", + "};\n", + "\n", + "mpl.figure.prototype.close_ws = function (fig, msg) {\n", + " fig.send_message('closing', msg);\n", + " // fig.ws.close()\n", + "};\n", + "\n", + "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", + " // Turn the data on the canvas into data in the output cell.\n", + " var width = this.canvas.width / this.ratio;\n", + " var dataURL = this.canvas.toDataURL();\n", + " this.cell_info[1]['text/html'] =\n", + " '';\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Tell IPython that the notebook contents must change.\n", + " IPython.notebook.set_dirty(true);\n", + " this.send_message('ack', {});\n", + " var fig = this;\n", + " // Wait a second, then push the new image to the DOM so\n", + " // that it is saved nicely (might be nice to debounce this).\n", + " setTimeout(function () {\n", + " fig.push_to_output();\n", + " }, 1000);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'btn-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " var button;\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " continue;\n", + " }\n", + "\n", + " button = fig.buttons[name] = document.createElement('button');\n", + " button.classList = 'btn btn-default';\n", + " button.href = '#';\n", + " button.title = name;\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message pull-right';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = document.createElement('div');\n", + " buttongrp.classList = 'btn-group inline pull-right';\n", + " button = document.createElement('button');\n", + " button.classList = 'btn btn-mini btn-primary';\n", + " button.href = '#';\n", + " button.title = 'Stop Interaction';\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', function (_evt) {\n", + " fig.handle_close(fig, {});\n", + " });\n", + " button.addEventListener(\n", + " 'mouseover',\n", + " on_mouseover_closure('Stop Interaction')\n", + " );\n", + " buttongrp.appendChild(button);\n", + " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", + " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", + "};\n", + "\n", + "mpl.figure.prototype._remove_fig_handler = function (event) {\n", + " var fig = event.data.fig;\n", + " if (event.target !== this) {\n", + " // Ignore bubbled events from children.\n", + " return;\n", + " }\n", + " fig.close_ws(fig, {});\n", + "};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (el) {\n", + " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (el) {\n", + " // this is important to make the div 'focusable\n", + " el.setAttribute('tabindex', 0);\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " } else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager) {\n", + " manager = IPython.keyboard_manager;\n", + " }\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which === 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " fig.ondownload(fig, null);\n", + "};\n", + "\n", + "mpl.find_output_cell = function (html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i = 0; i < ncells; i++) {\n", + " var cell = cells[i];\n", + " if (cell.cell_type === 'code') {\n", + " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", + " var data = cell.output_area.outputs[j];\n", + " if (data.data) {\n", + " // IPython >= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] === html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "};\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel !== null) {\n", + " IPython.notebook.kernel.comm_manager.register_target(\n", + " 'matplotlib',\n", + " mpl.mpl_figure_comm\n", + " );\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "cave.local_parameter_importance()" ] From 100cd638edf65717b17af553b63e224e2956fae3 Mon Sep 17 00:00:00 2001 From: JessicaBorja Date: Wed, 10 Mar 2021 13:23:38 +0100 Subject: [PATCH 04/22] cave plot experiments and analysis same as master --- mdp_playground/analysis/analysis.py | 574 +++++++++++++++++++++------- plot_experiments.ipynb | 43 ++- 2 files changed, 470 insertions(+), 147 deletions(-) diff --git a/mdp_playground/analysis/analysis.py b/mdp_playground/analysis/analysis.py index a8ff689..2a30411 100644 --- a/mdp_playground/analysis/analysis.py +++ b/mdp_playground/analysis/analysis.py @@ -1,19 +1,44 @@ import numpy as np import pandas as pd import matplotlib.pyplot as plt +from . import radar_chart import os import warnings +import math class MDPP_Analysis(): '''Utility class to load and plot data for analysis of experiments from MDP Playground - ''' - def __init__(self, save_folder = None): - self.save_folder = save_folder - - def load_data(self, dir_name, exp_name, num_metrics=3, load_eval=True): #, max_total_configs=200): - '''Loads training and evaluation data from given file + def __init__(self): + pass + def load_data(self, experiements: dict, load_eval=True): + '''Loads training and evaluation data from given multiple files + Parameters + ---------- + experiements : dict + per experiment -> key-value pair of exp_name & dir_name + dir_name : str + The location where the training and evaluation CSV files were written + exp_name : str + The name of the experiment: the training and evaluation CSV filenames are formed using this string + eg: experiments = { + "td3_move_to_a_point_action_max": "", + ..... + } + Returns + ------- + list of experiment data of type + [ for more details refer get_exp_data() ] + ''' + list_exp_data = [] + for exp_name, dir_name in experiements.items(): + exp_data = self.get_exp_data(dir_name, exp_name, load_eval=load_eval) + list_exp_data.append(exp_data) + return list_exp_data + + def get_exp_data(self, dir_name, exp_name, num_metrics=3, load_eval=True): #, max_total_configs=200): + '''get training and evaluation data from given experiement file Parameters ---------- dir_name : str @@ -24,9 +49,9 @@ def load_data(self, dir_name, exp_name, num_metrics=3, load_eval=True): #, max_t The number of metrics that were written to CSV stats files. Default is 3 (timesteps_total, episode_reward_mean, episode_len_mean). load_eval : bool Whether to load evaluation stats CSV or not. - Returns ------- + experiement data: dictionary type with following key-value train_stats : np.ndarray Training stats at end of training: 8-D tensor with 1st 6 dims the meta-features of MDP Playground, 7th dim is across the seeds, 8th dim is across different stats saved eval_stats : np.ndarray @@ -36,18 +61,14 @@ def load_data(self, dir_name, exp_name, num_metrics=3, load_eval=True): #, max_t eval_curves: np.ndarray The loaded evaluation CSV with the columns the evaluation stats that were saved ''' + stats_file = dir_name + '/' + exp_name #Name of file to which benchmark stats were written self.stats_file = stats_file - if self.save_folder is None: - self.save_folder = self.stats_file.split('/')[-1] - else: - self.save_folder = self.save_folder + self.stats_file.split('/')[-1] - #folder to save figures if os.path.isfile(stats_file + '.csv'): - print("\033[1;31mLoading data from a sequential run/already combined runs of experiment configurations.\033[0;0m") + print("Loading data from a sequential run/already combined runs of experiment configurations.") else: - print("\033[1;31mLoading data from a distributed run of experiment configurations. Creating a combined CSV stats file.\033[0;0m") + print("Loading data from a distributed run of experiment configurations. Creating a combined CSV stats file.") def join_files(file_prefix, file_suffix): '''Utility to join files that were written with different experiment configs''' with open(file_prefix + file_suffix, 'ab') as combined_file: @@ -75,40 +96,31 @@ def join_files(file_prefix, file_suffix): join_files(stats_file, '.csv') join_files(stats_file, '_eval.csv') - # Read column names - with open(stats_file + '.csv') as file_: - col_names = file_.readline().strip().split(', ') - col_names[0] = col_names[0][2:] # to remove '# ' that was written - # print("config_names:", col_names) - - stats_pd = pd.read_csv(stats_file + '.csv', skip_blank_lines=True,\ - header=None, names = col_names, comment='#', sep=' ') - self.stats_pd = stats_pd + stats_pd = pd.read_csv(stats_file + '.csv', skip_blank_lines=True, header=None, comment='#', sep=' ') + # print(stats_pd) + # print(stats_pd[11].dtypes) + # print(stats_pd.dtypes) print("Training stats read (rows, columns):", stats_pd.shape) + # Read column names + with open(stats_file + '.csv') as file_: + config_names = file_.readline().strip().split(', ') + config_names[0] = config_names[0][2:] # to remove '# ' that was written + # config_names[-1] = config_names[-1][:-1] # to remove ',' that was written + # print("config_names:", config_names) + self.config_names = config_names[1:] # ; begins at 1 to ignore training iteration num. ['Delay', 'Sequence Length', 'Reward Density', 'Terminal State Density', 'P Noise', 'R Noise', 'dummy_seed'] config_counts = [] dims_values = [] - #Keep only config_names that we wan't to measure - #traning iteration is always first, metrics are always last. - self.full_config_names = col_names.copy() - full_config_names = self.full_config_names - full_config_names.remove("training_iteration") - - # mean_vals = [ np.mean(stats_pd.loc[stats_pd['target_network_update_freq'] == val]["episode_reward_mean"]) - # for val in stats_pd["target_network_update_freq"].unique() ] - - #config counts includes seed - self.seed_idx = -1 - for i, c in enumerate(full_config_names[:-num_metrics]): # hardcoded 3 for no. of stats written - dims_values.append(stats_pd[c].unique()) - config_counts.append(stats_pd[c].nunique()) - if("seed" in c): - self.seed_idx = i - + # For the following seeds should always be last column read! 1st column should be >=1 (it should not be 0 because that is the training_iteration that was recorded and is not used here) + for i in range(1, len(config_names) - num_metrics): # hardcoded 3 for no. of stats written + dims_values.append(stats_pd[i].unique()) + config_counts.append(stats_pd[i].nunique()) + + # config_counts[2] = 1 # hack + # config_counts[-1] = 2 # hack for TD3 HP tuning files config_counts.append(num_metrics) #hardcoded number of training stats that were recorded config_counts = tuple(config_counts) - self.metric_names = full_config_names[-num_metrics:] - self.config_names = full_config_names[:-num_metrics] + self.metric_names = config_names[-num_metrics:] # Slice into training stats and get end of training stats for individual training runs in the experiment final_rows_for_a_config = [] @@ -116,18 +128,25 @@ def join_files(file_prefix, file_suffix): list_of_learning_curves = [] # cols_to_take = 8 - #Finding end configuration training for i in range(stats_pd.shape[0] - 1): - if stats_pd["timesteps_total"].iloc[i] > stats_pd["timesteps_total"].iloc[ i + 1]: + if stats_pd.iloc[i, -num_metrics] > stats_pd.iloc[i + 1, -num_metrics]: # hardcoded: -num_metrics column always HAS to be no. of timesteps for the current run + # list_of_learning_curves.append(stats_pd.iloc[previous_i:i+1, -cols_to_take:]) + previous_i = i + 1 final_rows_for_a_config.append(i) - + # print("i, previous_i:", i, previous_i) final_rows_for_a_config.append(i + 1) # Always append the last row! + # list_of_learning_curves.append(stats_pd.iloc[previous_i:i + 2, -cols_to_take:]) self.final_rows_for_a_config = final_rows_for_a_config + + # print(len(list_of_learning_curves)) + # print(len(final_rows_for_a_config)) stats_end_of_training = stats_pd.iloc[final_rows_for_a_config] - stats_reshaped = stats_end_of_training.iloc[:, -num_metrics:] # last vals are timesteps_total, episode_reward_mean, episode_len_mean + stats_reshaped = stats_end_of_training.iloc[:, -num_metrics:] # hardcoded # last vals are timesteps_total, episode_reward_mean, episode_len_mean stats_reshaped = np.reshape(np.array(stats_reshaped), config_counts) - + # print(stats_end_of_training.head(10)) print("train stats shape:", stats_reshaped.shape) +# to_plot_ = np.squeeze(stats_reshaped[:, :, :, :, 0, 0, :, 1]) +# print('Episode reward (at end of training) for 10 seeds for vanilla env.:', to_plot_) # Calculate AUC metrics train_aucs = [] @@ -143,10 +162,13 @@ def join_files(file_prefix, file_suffix): train_aucs = np.reshape(np.array(train_aucs), config_counts) print("train_aucs.shape:", train_aucs.shape) + + final_eval_metrics_reshaped, mean_data_eval, eval_aucs = None, None, None # Load evaluation stats # load_eval = False #hack ####TODO rectify if load_eval: + # Load evaluation stats stats_file_eval = stats_file + '_eval.csv' eval_stats = np.loadtxt(stats_file_eval, dtype=float) # print(eval_stats, eval_stats.shape) @@ -162,14 +184,14 @@ def join_files(file_prefix, file_suffix): hack_indices.append(i - len(hack_indices)) # appends index of last eval in this training_iteration i += 1 - # print("len(hack_indices), hack_indices[:5] and [:-5]:", len(hack_indices), hack_indices[:5], hack_indices[-5:]) + # print(len(hack_indices), hack_indices) if hack_indices[0] == 0: #hack hack_indices = hack_indices[1:] #hardcoded removes the 1st hack_index which is at position 0 so that hack_indices_10 below doesn't begin with a -10; apparently Ray seems to have changed logging for evaluation (using on_episode_end) from 0.7.3 to 0.9.0 ray_0_9_0 = True else: ray_0_9_0 = False hack_indices_10 = np.array(hack_indices) - 10 - # print(hack_indices_10.shape, hack_indices_10[:5], hack_indices_10[-5:]) + # print(hack_indices_10.shape, hack_indices_10) # print(np.array(hack_indices[1:]) - np.array(hack_indices[:-1])) # print("Min:", min(np.array(hack_indices[1:]) - np.array(hack_indices[:-1]))) # Some problem with Ray? Sometimes no. of eval episodes is less than 10. final_10_evals = [] @@ -187,19 +209,20 @@ def join_files(file_prefix, file_suffix): # print('final_rows_for_a_config', final_rows_for_a_config) # print("len(final_10_evals)", final_10_evals.shape, type(final_10_evals)) mean_data_eval = np.mean(final_10_evals, axis=1) # this is mean over last 10 eval episodes + # print(np.array(stats_pd.iloc[:, -3])) # Adds timesteps_total column to the eval stats which did not have them: mean_data_eval = np.concatenate((np.atleast_2d(np.array(stats_pd.iloc[:, -num_metrics])).T, mean_data_eval), axis=1) + # print(mean_data_eval.shape, len(final_rows_for_a_config)) final_eval_metrics_ = mean_data_eval[final_rows_for_a_config, :] # 1st column is episode reward, 2nd is episode length in original _eval.csv file, here it's 2nd and 3rd after prepending timesteps_total column above. # print(dims_values, config_counts) final_eval_metrics_reshaped = np.reshape(final_eval_metrics_, config_counts) # print(final_eval_metrics_) - + # print("eval stats shapes (before and after reshape):", final_eval_metrics_.shape, final_eval_metrics_reshaped.shape) print("eval stats shape:", final_eval_metrics_reshaped.shape) - # Calculate AUC metrics eval_aucs = [] for i in range(len(final_rows_for_a_config)): @@ -214,17 +237,14 @@ def join_files(file_prefix, file_suffix): eval_aucs = np.reshape(np.array(eval_aucs), config_counts) print("eval_aucs.shape:", eval_aucs.shape) - # -1 is added to ignore "no. of stats that were saved" as dimensions of difficulty - self.config_counts = config_counts[:-1] + self.config_counts = config_counts[:-1] # -1 is added to ignore "no. of stats that were saved" as dimensions of difficulty self.dims_values = dims_values # Catpure the dimensions that were varied, i.e. ones which had more than 1 value across experiments x_axis_labels = [] x_tick_labels_ = [] dims_varied = [] - for i in range(len(self.config_counts)): - if("seed" in self.config_names[i]): # ignore #seeds as dimensions of difficulty - continue + for i in range(len(self.config_counts) - 1): # -1 is added to ignore #seeds as dimensions of difficulty if self.config_counts[i]> 1: x_axis_labels.append(self.config_names[i]) x_tick_labels_.append([str(j) for j in self.dims_values[i]]) @@ -258,148 +278,346 @@ def join_files(file_prefix, file_suffix): for d,v,i in zip(x_axis_labels, x_tick_labels_, dims_varied): print("Dimension varied:", d, ". The values it took:", v, ". Number of values it took:", config_counts[i], ". Index in loaded data:", i) - return stats_reshaped, final_eval_metrics_reshaped, np.array(stats_pd), mean_data_eval, train_aucs, eval_aucs + # experiement data + exp_data = dict() + # related to training & eval data + exp_data['train_stats'] = train_aucs + exp_data['eval_stats'] = eval_aucs + exp_data['train_curves'] = np.array(stats_pd) + exp_data['eval_curves'] = mean_data_eval + + # related to plots + exp_data['metric_names'] = self.metric_names + exp_data['tick_labels'] = self.tick_labels + exp_data['axis_labels'] = self.axis_labels + exp_data['stats_file'] = self.stats_file + exp_data['algorithm'] = self.dims_values[0][0] + exp_data['dims_varied'] = self.dims_varied + exp_data['config_counts'] = self.config_counts + exp_data['final_rows_for_a_config'] = self.final_rows_for_a_config + exp_data['config_names'] = self.config_names + exp_data['dims_values'] = self.dims_values + + return exp_data + + + def gather_stats(self, list_exp_data, train, metric_num, plot_type): + stats_data = dict() + + if plot_type is "agent": + #groupby agent + groupby = 'algorithm' + sub_groupby = 'axis_labels' + elif plot_type is "metric": + #groupby metric + groupby = 'axis_labels' + sub_groupby = 'algorithm' + + #iterate and group data based on the their values eg. ['SAC', 'TD3'] or ['action_space_max', 'time_unit'] + """ + example of experiment data grouped by agent: + { + + "SAC": { + + "time_unit": { + "to_plot_": [], + "to_plot_std_": [], + .... + }, + "action_space_max": { + "to_plot_": [], + "to_plot_std_": [], + .... + }, + ........ + }, + "TD3": { + ...... + } + } + """ + for exp_data in list_exp_data: + if train: + stats = exp_data['train_stats'] + else: + stats = exp_data['eval_stats'] - def plot_1d_dimensions(self, stats_data, save_fig=False, train=True, metric_num=-2): - '''Plots 1-D bar plots across a single dimension with mean and std. dev. + group_keys = exp_data[groupby] + if isinstance(group_keys, str): + group_keys = [group_keys] + + for group_key in group_keys: + if group_key not in stats_data: + # if group_key is not alreay present initialize + stats_data[group_key] = dict() + + sub_group_keys = exp_data[sub_groupby] + if isinstance(sub_group_keys, str): + sub_group_keys = [sub_group_keys] + + for idx in range(len(sub_group_keys)): + sub_group_key = sub_group_keys[idx] + if sub_group_key not in stats_data[group_key]: + # if sub_group_key is not alreay present initialize + stats_data[group_key][sub_group_key] = dict() + + + # gather data related to plot + mean_data_ = np.mean(stats[..., metric_num], axis=-1) # the slice sub-selects the metric written in position metric_num from the "last axis of diff. metrics that were written" and then the axis of #seeds becomes axis=-1 ( before slice it was -2). + to_plot_ = np.squeeze(mean_data_) + + #HACK traspose the array and choose first column elements always + if len(to_plot_.shape) > 1: + axes = np.arange(len(to_plot_.shape)) + new_axes = [axes[(i - idx) % len(axes)] for i, x in enumerate(axes)] + to_plot_ = np.transpose(to_plot_, tuple(new_axes))[:, 0] + stats_data[group_key][sub_group_key]['to_plot_'] = to_plot_ + + std_dev_ = np.std(stats[..., metric_num], axis=-1) #seed + to_plot_std_ = np.squeeze(std_dev_) + #HACK traspose the array and choose first column elements always + if len(to_plot_std_.shape) > 1: + to_plot_std_ = np.transpose(to_plot_std_, tuple(new_axes))[:, 0] + stats_data[group_key][sub_group_key]['to_plot_std_'] = to_plot_std_ + + stats_data[group_key][sub_group_key]['labels'] = sub_group_key + stats_data[group_key][sub_group_key]['tick_labels'] = exp_data['tick_labels'][idx] + stats_data[group_key][sub_group_key]['axis_labels'] = exp_data[groupby] + stats_data[group_key][sub_group_key]['metric_names'] = exp_data['metric_names'] + stats_data[group_key][sub_group_key]['stats_file'] = exp_data['stats_file'] + + return stats_data + + def plot_1d_dimensions(self, list_exp_data, save_fig=False, train=True, metric_num=-2, plot_type = "agent"): + '''Plots 1-D bar plots across a single dimension with mean and std. dev. Parameters ---------- - stats_data : np.array - 8-D tensor with 1st 6 dims the meta-features of MDP Playground, 7th dim is across the seeds, 8th dim is across different stats saved + list_exp_data : list of experiment data of type + [ for more details refer load_data(), get_exp_data() ] save_fig : bool, optional - A flag used to save a PDF (default is - False) + A flag used to save a PDF (default is False) train : bool, optional A flag used to insert either _train or _eval in the filename of the PDF (default is True) + metric_num : + allowed values-> '-1' to plot episode mean lengths + '-2' to plot episode reward + plot_type : string describing how to group data and plot, say based on agent or metric + allowed values-> ['agent' ,'metric'] + ''' + + stats_data = self.gather_stats(list_exp_data, train, metric_num, plot_type) + + #plot + for group_key in stats_data.keys(): + cols = 4 # hard-coded value + rows = math.ceil((len(stats_data[group_key].keys())/cols)) # dynamically compute + + plt.rcParams.update({'font.size': 18}) # default 12, for poster: 30 + plt.rcParams['figure.figsize'] = [7 * cols, 5 * rows] + + figure, axes = plt.subplots(nrows=rows, ncols=cols) # [n*1] or [n*2] grid + + i = j = 0 + colors = ['blue', 'orange', 'green', 'purple', 'cyan', 'olive', 'brown', 'grey', 'red', 'pink'] + for sub_group_key, color in zip(stats_data[group_key].keys(), colors): + if cols == 1 and rows == 1: + #single row, single column plot + self.plot_bar(axes, stats_data[group_key][sub_group_key], save_fig, metric_num, color) + elif rows ==1 : + #single row, multiple column plot + self.plot_bar(axes[j], stats_data[group_key][sub_group_key], save_fig, metric_num, color) + j +=1 + else : + #multiple row, multiple column plot + self.plot_bar(axes[i, j], stats_data[group_key][sub_group_key], save_fig, metric_num, color) + if j == cols-1: + #switch to next row 1st column + j = 0 + i += 1 + else: + #switch to same row next column + j += 1 + + # hide the blank plot (if any) + if j > 0 and j <= cols-1: + while j <= cols-1: + if i == 0: + #axes[j].set_visible(False) + axes[j].axis('off') + else: + #axes[i, j].set_visible(False) + axes[i, j].axis('off') + j += 1 + + figure.tight_layout(pad=3.0) + figure.suptitle(group_key, x=0.2, y=1, fontsize=24, fontweight='bold') + + # save figure + if save_fig: + fig_name = stats_data[group_key][sub_group_key]['stats_file'].split('/')[-1] + \ + ('_train' if train else '_eval') + '_final_reward_' + \ + stats_data[group_key][sub_group_key]['axis_labels'].replace(' ','_') + \ + '_' + str(stats_data[group_key][sub_group_key]['metric_names'][metric_num]) + '_1d.pdf' + plt.savefig(fig_name, dpi=300, bbox_inches="tight") + + plt.show() + def plot_bar(self, ax, stats_data, save_fig=False, metric_num=-2, bar_color='blue'): + '''Plots 1-D bar plots across a single dimension with mean and std. dev. + Parameters + ---------- + ax: matplotlib axes instance to plot + stats_data : dictionary type with data related to ['train_stats', 'eval_stats', ...] + [ for more details refer load_data(), get_exp_data() ] + save_fig : bool, optional + A flag used to save a PDF (default is False) + metric_num : + allowed values-> '-1' to plot episode mean lengths + '-2' to plot episode reward + bar_color : the color of bars in plots ''' - y_axis_label = 'Reward' if 'reward' in self.metric_names[metric_num] else self.metric_names[metric_num] + y_axis_label = 'Reward' if 'reward' in stats_data['metric_names'][metric_num] else stats_data['metric_names'][metric_num] - plt.rcParams.update({'font.size': 18}) # default 12, for poster: 30 - # print(stats_data.shape) - # self.seed_ix is -1 if none found/ default - mean_data_ = np.mean(stats_data[..., metric_num], axis=self.seed_idx) # the slice sub-selects the metric written in position metric_num from the "last axis of diff. metrics that were written" and then the axis of #seeds becomes axis=-1 ( before slice it was -2). + to_plot_ = stats_data['to_plot_'] + to_plot_std_ = stats_data['to_plot_std_'] + labels = stats_data['labels'] + tick_labels = stats_data['tick_labels'] + axis_labels = stats_data['axis_labels'] + stats_file = stats_data['stats_file'] - to_plot_ = np.squeeze(mean_data_) - std_dev_ = np.std(stats_data[..., metric_num], axis=self.seed_idx) #seed - to_plot_std_ = np.squeeze(std_dev_) + x = np.arange(len(tick_labels)) + width = (x[1]-x[0])*0.8 # bar width - fig_width = len(self.tick_labels[0]) - # plt.figure() - plt.figure(figsize=(fig_width, 1.5)) + ax.bar(x, to_plot_, width, yerr=to_plot_std_, label=labels, color=bar_color) - # print(to_plot_.shape) - if len(to_plot_.shape) == 2: # Case when 2 meta-features were varied - plt.bar(self.tick_labels[0], to_plot_[:, 0], yerr=to_plot_std_[:, 0]) - else: - plt.bar(self.tick_labels[0], to_plot_, yerr=to_plot_std_) - plt.xlabel(self.axis_labels[0]) - plt.ylabel(y_axis_label) - if save_fig: - x = self.save_folder + ('_train' if train else '_eval') + '_final_reward_' + self.axis_labels[0].replace(' ','_') + '_' + str(self.metric_names[metric_num]) + '_1d.pdf' - plt.savefig(self.save_folder + ('_train' if train else '_eval') + '_final_reward_' + self.axis_labels[0].replace(' ','_') + '_' + str(self.metric_names[metric_num]) + '_1d.pdf', dpi=300, bbox_inches="tight") - plt.show() + ax.set_ylabel(y_axis_label) + #ax.set_xlabel(axis_labels) + ax.set_xticks(x) + #ax.set_title(labels) + ax.legend(loc='upper right') + ax.set_xticklabels(tick_labels) - if len(to_plot_.shape) == 2: # Case when 2 meta-features were varied - fig_width = len(self.tick_labels[1]) - plt.figure(figsize=(fig_width, 1.5)) - plt.bar(self.tick_labels[1], to_plot_[0, :], yerr=to_plot_std_[0, :]) - # plt.tight_layout() - plt.xlabel(self.axis_labels[1]) - plt.ylabel(y_axis_label) - if save_fig: - plt.savefig(self.save_folder+ ('_train' if train else '_eval') + '_final_reward_' + self.axis_labels[1].replace(' ','_') + '_' + str(self.metric_names[metric_num]) + '_1d.pdf', dpi=300, bbox_inches="tight") - plt.show() - def plot_2d_heatmap(self, stats_data, save_fig=False, train=True, metric_num=-2): + def plot_2d_heatmap(self, list_exp_data, save_fig=False, train=True, metric_num=-2): '''Plots 2 2-D heatmaps: 1 for mean and 1 for std. dev. across 2 meta-features of MDP Playground - Parameters ---------- - stats_data : np.array - 8-D tensor with 1st 6 dims the meta-features of MDP Playground, 7th dim is across the seeds, 8th dim is across different stats saved + list_exp_data : list of experiment data of type + [ for more details refer load_data(), get_exp_data() ] save_fig : bool, optional - A flag used to save a PDF (default is - False) + A flag used to save a PDF (default is False) train : bool, optional A flag used to insert either _train or _eval in the filename of the PDF (default is True) ''' + #HACK + if len(list_exp_data) > 0: + exp_data = list_exp_data[0] #TODO make changes to handle multiple experiements plot + else: + return + + plt.rcParams.update({'font.size': 18}) # default 12, 24 for paper, for poster: 30 cmap = 'Purples' # 'Blues' # - label_ = 'Reward' if 'reward' in self.metric_names[metric_num] else self.metric_names[metric_num] + label_ = 'Reward' if 'reward' in exp_data['metric_names'][metric_num] else exp_data['metric_names'][metric_num] + + tick_labels = exp_data['tick_labels'] + axis_labels = exp_data['axis_labels'] + stats_file = exp_data['stats_file'] - mean_data_ = np.mean(stats_data[..., metric_num], axis=self.seed_idx) #seed + if train: + stats_data = exp_data['train_stats'] + else: + stats_data = exp_data['eval_stats'] + + mean_data_ = np.mean(stats_data[..., metric_num], axis=-1) #seed to_plot_ = np.squeeze(mean_data_) # print(to_plot_) if len(to_plot_.shape) > 2: # warning.warn("Data contains variation in more than 2 dimensions (apart from seeds). May lead to plotting error!") raise ValueError("Data contains variation in more than 2 dimensions (apart from seeds). This is currently not supported") #TODO Add 2-D plots for all combinations of 2 varying dims? plt.imshow(np.atleast_2d(to_plot_), cmap=cmap, interpolation='none', vmin=0, vmax=np.max(to_plot_)) - if len(self.tick_labels) == 2: - plt.gca().set_xticklabels(self.tick_labels[1]) - plt.gca().set_yticklabels(self.tick_labels[0]) + if len(tick_labels) == 2: + plt.gca().set_xticklabels(tick_labels[1]) + plt.gca().set_yticklabels(tick_labels[0]) else: - plt.gca().set_xticklabels(self.tick_labels[0]) + plt.gca().set_xticklabels(tick_labels[0]) cbar = plt.colorbar() cbar.ax.get_yaxis().labelpad = 15 # default 15, for poster: 25 cbar.set_label(label_, rotation=270) - if len(self.axis_labels) == 2: - plt.xlabel(self.axis_labels[1]) - plt.ylabel(self.axis_labels[0]) + if len(axis_labels) == 2: + plt.xlabel(axis_labels[1]) + plt.ylabel(axis_labels[0]) else: - plt.xlabel(self.axis_labels[0]) + plt.xlabel(axis_labels[0]) if save_fig: - plt.savefig(self.save_folder + ('_train' if train else '_eval') + '_final_reward_mean_heat_map_' + str(self.metric_names[metric_num]) + '.pdf', dpi=300, bbox_inches="tight") + plt.savefig(stats_file.split('/')[-1] + ('_train' if train else '_eval') + '_final_reward_mean_heat_map_' + str(exp_data['metric_names'][metric_num]) + '.pdf', dpi=300, bbox_inches="tight") plt.show() - std_dev_ = np.std(stats_data[..., metric_num], axis=self.seed_idx) #seed + std_dev_ = np.std(stats_data[..., metric_num], axis=-1) #seed to_plot_ = np.squeeze(std_dev_) # print(to_plot_, to_plot_.shape) plt.imshow(np.atleast_2d(to_plot_), cmap=cmap, interpolation='none', vmin=0, vmax=np.max(to_plot_)) # 60 for DQN, 100 for A3C - if len(self.tick_labels) == 2: - plt.gca().set_xticklabels(self.tick_labels[1]) - plt.gca().set_yticklabels([str(i) for i in self.tick_labels[0]]) + if len(tick_labels) == 2: + plt.gca().set_xticklabels(tick_labels[1]) + plt.gca().set_yticklabels([str(i) for i in tick_labels[0]]) else: - plt.gca().set_xticklabels(self.tick_labels[0]) + plt.gca().set_xticklabels(tick_labels[0]) cbar = plt.colorbar() cbar.ax.get_yaxis().labelpad = 15 # default 15, for poster: 30 cbar.set_label('Reward Std Dev.', rotation=270) - if len(self.axis_labels) == 2: - plt.xlabel(self.axis_labels[1]) - plt.ylabel(self.axis_labels[0]) + if len(axis_labels) == 2: + plt.xlabel(axis_labels[1]) + plt.ylabel(axis_labels[0]) else: - plt.xlabel(self.axis_labels[0]) + plt.xlabel(axis_labels[0]) # plt.tight_layout() if save_fig: - plt.savefig(self.save_folder + ('_train' if train else '_eval') + '_final_reward_std_heat_map_' + str(self.metric_names[metric_num]) + '.pdf', dpi=300, bbox_inches="tight") + plt.savefig(stats_file.split('/')[-1] + ('_train' if train else '_eval') + '_final_reward_std_heat_map_' + str(exp_data['metric_names'][metric_num]) + '.pdf', dpi=300, bbox_inches="tight") # plt.savefig(stats_file.split('/')[-1] + '_train_heat_map.png')#, dpi=300) plt.show() - def plot_learning_curves(self, stats_data, save_fig=False, train=True, metric_num=-2): # metric_num needs to be minus indexed because stats_pd reutrned for train stats has _all_ columns + def plot_learning_curves(self, list_exp_data, save_fig=False, train=True, metric_num=-2): # metric_num needs to be minus indexed because stats_pd reutrned for train stats has _all_ columns '''Plots learning curves: Either across 1 or 2 meta-features of MDP Playground. Different colours represent learning curves for different seeds. - Parameters ---------- - stats_data : np.array - 8-D tensor with 1st 6 dims the meta-features of MDP Playground, 7th dim is across the seeds, 8th dim is across different stats saved + list_exp_data : list of experiment data of type + [ for more details refer load_data(), get_exp_data() ] save_fig : bool, optional - A flag used to save a PDF (default is - False) + A flag used to save a PDF (default is False) train : bool, optional A flag used to insert either _train or _eval in the filename of the PDF (default is True) ''' + #HACK + if len(list_exp_data) > 0: + exp_data = list_exp_data[0] #TODO make changes to handle multiple experiements plot + else: + return + + + stats_file = exp_data['stats_file'] + dims_varied = exp_data['dims_varied'] + config_counts = exp_data['config_counts'] + config_names = exp_data['config_names'] + dims_values = exp_data['dims_values'] + final_rows_for_a_config = exp_data['final_rows_for_a_config'] + if train: + stats_data = exp_data['train_curves'] + else: + stats_data = exp_data['eval_curves'] + # Plot for train metrics: learning curves; with subplot # Comment out unneeded labels in code lines 41-44 in this cell - if len(self.dims_varied) > 1: - ncols_ = self.config_counts[self.dims_varied[1]] - nrows_ = self.config_counts[self.dims_varied[0]] + if len(dims_varied) > 1: + ncols_ = config_counts[dims_varied[1]] + nrows_ = config_counts[dims_varied[0]] else: - ncols_ = self.config_counts[self.dims_varied[0]] + ncols_ = config_counts[dims_varied[0]] nrows_ = 1 - nseeds_ = self.stats_pd[self.full_config_names[self.seed_idx]].nunique()#self.config_counts[-1] + nseeds_ = config_counts[-1] # print(ax, type(ax), type(ax[0])) - #color_cycle = plt.rcParams['axes.prop_cycle'].by_key()['color'] +# color_cycle = plt.rcParams['axes.prop_cycle'].by_key()['color'] # print("color_cycle", color_cycle) plt.rcParams.update({'font.size': 25}) # 25 for 36x21 fig, 16 for 24x14 fig. # 36x21 for better resolution but about 900kb file size, 24x14 for okay resolution and 550kb file size @@ -407,15 +625,15 @@ def plot_learning_curves(self, stats_data, save_fig=False, train=True, metric_nu ax = np.atleast_2d(ax) # metrics_reshaped_squeezed = np.squeeze(metrics_reshaped) # print(np.squeeze(metrics_reshaped).shape) - for i in range(len(self.final_rows_for_a_config)): + for i in range(len(final_rows_for_a_config)): i_index = i//(nseeds_ * ncols_) # = num_seeds * shape of more frequently changing hyperparam j_index = (i//nseeds_) % ncols_ # if i == 0: - to_plot_ = stats_data[0:self.final_rows_for_a_config[i]+1, metric_num] - to_plot_x = stats_data[0:self.final_rows_for_a_config[i]+1,-3] + to_plot_ = stats_data[0:final_rows_for_a_config[i]+1, metric_num] + to_plot_x = stats_data[0:final_rows_for_a_config[i]+1,-3] else: - to_plot_ = stats_data[self.final_rows_for_a_config[i-1]+1:self.final_rows_for_a_config[i]+1, metric_num] - to_plot_x = stats_data[self.final_rows_for_a_config[i-1]+1:self.final_rows_for_a_config[i]+1, -3] + to_plot_ = stats_data[final_rows_for_a_config[i-1]+1:final_rows_for_a_config[i]+1, metric_num] + to_plot_x = stats_data[final_rows_for_a_config[i-1]+1:final_rows_for_a_config[i]+1, -3] # print(to_plot_[-1]) # if i % 10 == 0: # fig = plt.figure(figsize=(12, 7)) @@ -427,13 +645,13 @@ def plot_learning_curves(self, stats_data, save_fig=False, train=True, metric_nu ax[i_index][j_index].set_xlabel("Train Timesteps") ax[i_index][j_index].set_ylabel("Reward") # ax[i_index][j_index].set_title('Delay ' + str(delays[i_index]) + ', Sequence Length ' + str(sequence_lengths[j_index])) - if len(self.dims_varied) > 1: - title_1st_dim = self.config_names[self.dims_varied[0]] + ' ' + str(self.dims_values[self.dims_varied[0]][i_index]) - title_2nd_dim = self.config_names[self.dims_varied[1]] + ' ' + str(self.dims_values[self.dims_varied[1]][j_index]) - ax[i_index][j_index].set_title(title_1st_dim + ', ' + title_2nd_dim) + if len(dims_varied) > 1: + title_1st_dim = config_names[dims_varied[0]] + ' ' + str(dims_values[dims_varied[0]][i_index]) + title_2nd_dim = config_names[dims_varied[1]] + ' ' + str(dims_values[dims_varied[1]][j_index]) else: - title_1st_dim = self.config_names[self.dims_varied[0]] + ' ' + str(self.dims_values[self.dims_varied[0]][j_index]) - ax[i_index][j_index].set_title(title_1st_dim) + title_1st_dim = config_names[dims_varied[0]] + ' ' + str(dims_values[dims_varied[0]][j_index]) + title_2nd_dim = '' + ax[i_index][j_index].set_title(title_1st_dim + ', ' + title_2nd_dim) # ax[i_index][j_index].set_title('Sequence Length ' + str(seq_lens[j_index])) # ax[i_index][j_index].set_title('Reward Density ' + str(reward_densities[j_index])) @@ -442,4 +660,68 @@ def plot_learning_curves(self, stats_data, save_fig=False, train=True, metric_nu # plt.suptitle("Training Learning Curves") plt.show() if save_fig: - fig.savefig(self.save_folder + ('_train' if train else '_eval') + '_learning_curves_' + str(self.metric_names[metric_num]) + '.pdf', dpi=300, bbox_inches="tight") # Generates high quality vector graphic PDF 125kb; dpi doesn't matter for this + fig.savefig(stats_file.split('/')[-1] + ('_train' if train else '_eval') + '_learning_curves_' + str(exp_data['metric_names'][metric_num]) + '.pdf', dpi=300, bbox_inches="tight") # Generates high quality vector graphic PDF 125kb; dpi doesn't matter for this + + ###### ---------- radar (spider) plot ------------- ###### + def plot_radar(self, list_exp_data, save_fig=False, train=True, metric_num=-2, plot_type="agent", weights={}): + '''Plots radar (spider) chart across different dimensions + Parameters + ---------- + list_exp_data : list of experiment data of type + [ for more details refer load_data(), get_exp_data() ] + save_fig : bool, optional + A flag used to save a PDF (default is False) + train : bool, optional + A flag used to insert either _train or _eval in the filename of the PDF (default is True) + metric_num : + allowed values-> '-1' to plot episode mean lengths + '-2' to plot episode reward + plot_type : string describing how to group data and plot, say based on agent or metric + allowed values-> ['agent' ,'metric'] + weights : dictionary of weights associated per dimension (plot_type) data + eg weights['reward_noise'] = [.25, .25, .25, .25] + ''' + + stats_data = self.gather_stats(list_exp_data, train, metric_num, plot_type) + + # get axes labels + first_group = next(iter(stats_data.values())) + spoke_labels = first_group.keys() + + #plot + N = len(spoke_labels) + theta = radar_chart.radar_factory(N, frame='circle') + plt.rcParams['figure.figsize'] = [7, 5] + ax = plt.subplot(111, projection='radar') + + colors = ['blue', 'orange', 'green', 'purple', 'cyan', 'olive', 'brown', 'grey', 'red', 'pink'] + for group_key, color in zip(stats_data.keys(), colors): + d = [] + for sub_group_key in stats_data[group_key].keys(): + data = stats_data[group_key][sub_group_key]['to_plot_'] + if sub_group_key in weights: + d.append(np.average(data, axis=0, weights=weights[sub_group_key])) + else: + d.append(np.average(data)) + + ax.plot(theta, d, color=color) + ax.fill(theta, d, facecolor=color, alpha=0.25) + + # customize plot axis labels + ax.set_varlabels(spoke_labels) + ax.set_rlabel_position(0) + plt.xticks(color="black", fontsize=12) + plt.yticks(color="black", fontsize=10) + + labels = stats_data.keys() + legend = ax.legend(labels, loc=(0.9, .95), labelspacing=0.1, fontsize=12) + + # save figure + if save_fig: + fig_name = stats_data[group_key][sub_group_key]['stats_file'].split('/')[-1] + \ + ('_train' if train else '_eval') + '_final_reward_' + \ + stats_data[group_key][sub_group_key]['axis_labels'].replace(' ','_') + \ + '_' + str(stats_data[group_key][sub_group_key]['metric_names'][metric_num]) + '_spider.pdf' + plt.savefig(fig_name, dpi=300, bbox_inches="tight") + + plt.show() \ No newline at end of file diff --git a/plot_experiments.ipynb b/plot_experiments.ipynb index 375853a..7fcaf50 100644 --- a/plot_experiments.ipynb +++ b/plot_experiments.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -168,6 +168,47 @@ "mdpp_analysis.plot_learning_curves(list_exp_data, save_fig, train=False)" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Setup to analyse an MDP Playground experiment\n", + "from mdp_playground.analysis import MDPP_Analysis\n", + "# Set dir_name to the location where the CSV files from running an experiment were saved\n", + "dir_name = '../mdp_files/'\n", + "# Set exp_name to the name that was given to the experiment when running it\n", + "exp_name = 'dqn_seq_del'\n", + "# Set the following to True to save PDFs of plots that you generate below\n", + "save_fig = True\n", + "\n", + "from cave.cavefacade import CAVE\n", + "from mdp_playground.analysis.mdpp_to_cave import MDPPToCave\n", + "import os\n", + "\n", + "#The converted mdpp csvs will be stored in output_dir\n", + "output_dir = \"../mdpp_to_cave\"\n", + "mdpp_cave = MDPPToCave(output_dir)\n", + "cave_input_file = mdpp_cave.to_bohb_results(dir_name, exp_name)\n", + "\n", + "cave_input_file = \"../mdpp_to_cave/%s\"%exp_name\n", + "\n", + "# Similarly, as an example, cave will ouput it's results \n", + "# to the same directory as cave's input files\n", + "\n", + "cave_results = os.path.join(cave_input_file, \"out\")\n", + "cave = CAVE(folders = [cave_input_file],\n", + " output_dir = cave_results,\n", + " ta_exec_dir = [cave_input_file],\n", + " file_format = \"BOHB\",\n", + " show_jupyter=True,\n", + " )\n", + "cave.performance_table()\n", + "cave.local_parameter_importance()\n", + "cave.cave_fanova()" + ] + }, { "cell_type": "code", "execution_count": null, From 57c60ad81e51726c0c00915ac7f46ff6ca4ef232 Mon Sep 17 00:00:00 2001 From: Jessica Borja Date: Thu, 25 Mar 2021 00:17:03 +0100 Subject: [PATCH 05/22] changes to match master --- experiments/a3c_del.py | 105 + experiments/a3c_lstm_del.py | 15 +- experiments/a3c_lstm_seq.py | 13 +- experiments/a3c_seq.py | 104 + plot_experiments.ipynb | 4286 +++++++++++++++++++++++++++++++++- run_experiments_baselines.py | 100 +- run_experiments_ray.py | 65 +- setup.py | 4 + test_cave_analysis.py | 32 + 9 files changed, 4616 insertions(+), 108 deletions(-) create mode 100644 experiments/a3c_del.py create mode 100644 experiments/a3c_seq.py create mode 100644 test_cave_analysis.py diff --git a/experiments/a3c_del.py b/experiments/a3c_del.py new file mode 100644 index 0000000..a42e0dc --- /dev/null +++ b/experiments/a3c_del.py @@ -0,0 +1,105 @@ +num_seeds = 10 +from collections import OrderedDict +var_env_configs = OrderedDict({ + 'state_space_size': [8],#, 10, 12, 14] # [2**i for i in range(1,6)] + 'action_space_size': [8],#2, 4, 8, 16] # [2**i for i in range(1,6)] + 'delay': [0] + [2**i for i in range(4)], + 'sequence_length': [1], + 'reward_density': [0.25], # np.linspace(0.0, 1.0, num=5) + 'make_denser': [False], + 'terminal_state_density': [0.25], # np.linspace(0.1, 1.0, num=5) + 'transition_noise': [0],#, 0.01, 0.02, 0.10, 0.25] + 'reward_noise': [0],#, 1, 5, 10, 25] # Std dev. of normal dist. + 'dummy_seed': [i for i in range(num_seeds)], +}) + +var_configs = OrderedDict({ +"env": var_env_configs +}) + +env_config = { + "env": "RLToy-v0", + "horizon": 100, + "env_config": { + 'seed': 0, #seed + 'state_space_type': 'discrete', + 'action_space_type': 'discrete', + 'generate_random_mdp': True, + 'repeats_in_sequences': False, + 'reward_scale': 1.0, + 'completely_connected': True, + }, +} + +timesteps_total = 1e6 +algorithm = "A3C" +agent_config = { + # Size of rollout batch + "sample_batch_size": 10, # maybe num_workers * sample_batch_size * num_envs_per_worker * grads_per_step + "train_batch_size": 100, # seems to have no effect + # Use PyTorch as backend - no LSTM support + "use_pytorch": False, + # GAE(gamma) parameter + "gamma": 0.99, + "lambda": 0.95, # + # Max global norm for each gradient calculated by worker + "grad_clip": 10.0, # low prio. + # Learning rate + "lr": 0.0001, # + # Learning rate schedule + "lr_schedule": None, + # Value Function Loss coefficient + "vf_loss_coeff": 0.1, # + # Entropy coefficient + "entropy_coeff": 0.1, # + # Min time per iteration + "min_iter_time_s": 0, + # Workers sample async. Note that this increases the effective + # sample_batch_size by up to 5x due to async buffering of batches. + "sample_async": True, + "timesteps_per_iteration": 1000, + "num_workers": 3, + "num_envs_per_worker": 5, + + "optimizer": { + "grads_per_step": 10 + }, +} + +model_config = { + "model": { + "fcnet_hiddens": [128, 128, 128], + "custom_preprocessor": "ohe", + "custom_options": {}, # extra options to pass to your preprocessor + "fcnet_activation": "tanh", + "use_lstm": False, + }, +} + +from ray import tune +eval_config = { + "evaluation_interval": 1, # I think this means every x training_iterations + "evaluation_config": { + "explore": False, + "exploration_fraction": 0, + "exploration_final_eps": 0, + "evaluation_num_episodes": 10, + "horizon": 100, + "env_config": { + "dummy_eval": True, #hack Used to check if we are in evaluation mode or training mode inside Ray callback on_episode_end() to be able to write eval stats + 'transition_noise': 0 if "state_space_type" in env_config["env_config"] and env_config["env_config"]["state_space_type"] == "discrete" else tune.function(lambda a: a.normal(0, 0)), + 'reward_noise': tune.function(lambda a: a.normal(0, 0)), + 'action_loss_weight': 0.0, + } + }, +} + +value_tuples = [] +for config_type, config_dict in var_configs.items(): + for key in config_dict: + assert type(var_configs[config_type][key]) == list, "var_config should be a dict of dicts with lists as the leaf values to allow each configuration option to take multiple possible values" + value_tuples.append(var_configs[config_type][key]) + +import itertools +cartesian_product_configs = list(itertools.product(*value_tuples)) +print("Total number of configs. to run:", len(cartesian_product_configs)) diff --git a/experiments/a3c_lstm_del.py b/experiments/a3c_lstm_del.py index 20e3ecf..0fa84ef 100644 --- a/experiments/a3c_lstm_del.py +++ b/experiments/a3c_lstm_del.py @@ -40,7 +40,8 @@ # Use PyTorch as backend - no LSTM support "use_pytorch": False, # GAE(gamma) parameter - "lambda": 0.0, # + "gamma": 0.99, + "lambda": 0.95, # # Max global norm for each gradient calculated by worker "grad_clip": 10.0, # low prio. # Learning rate @@ -61,7 +62,7 @@ "num_envs_per_worker": 5, "optimizer": { - "grads_per_step": 10 + "grads_per_step": 1 }, } @@ -94,3 +95,13 @@ } }, } + +value_tuples = [] +for config_type, config_dict in var_configs.items(): + for key in config_dict: + assert type(var_configs[config_type][key]) == list, "var_config should be a dict of dicts with lists as the leaf values to allow each configuration option to take multiple possible values" + value_tuples.append(var_configs[config_type][key]) + +import itertools +cartesian_product_configs = list(itertools.product(*value_tuples)) +print("Total number of configs. to run:", len(cartesian_product_configs)) diff --git a/experiments/a3c_lstm_seq.py b/experiments/a3c_lstm_seq.py index 503945e..bf988ac 100644 --- a/experiments/a3c_lstm_seq.py +++ b/experiments/a3c_lstm_seq.py @@ -39,7 +39,8 @@ # Use PyTorch as backend - no LSTM support "use_pytorch": False, # GAE(gamma) parameter - "lambda": 0.0, # + "gamma": 0.99, + "lambda": 0.95, # # Max global norm for each gradient calculated by worker "grad_clip": 10.0, # low prio. # Learning rate @@ -93,3 +94,13 @@ } }, } + +value_tuples = [] +for config_type, config_dict in var_configs.items(): + for key in config_dict: + assert type(var_configs[config_type][key]) == list, "var_config should be a dict of dicts with lists as the leaf values to allow each configuration option to take multiple possible values" + value_tuples.append(var_configs[config_type][key]) + +import itertools +cartesian_product_configs = list(itertools.product(*value_tuples)) +print("Total number of configs. to run:", len(cartesian_product_configs)) diff --git a/experiments/a3c_seq.py b/experiments/a3c_seq.py new file mode 100644 index 0000000..acdc635 --- /dev/null +++ b/experiments/a3c_seq.py @@ -0,0 +1,104 @@ +num_seeds = 10 +from collections import OrderedDict +var_env_configs = OrderedDict({ + 'state_space_size': [8],#, 10, 12, 14] # [2**i for i in range(1,6)] + 'action_space_size': [8],#2, 4, 8, 16] # [2**i for i in range(1,6)] + 'delay': [0], + 'sequence_length': [1, 2, 3, 4],#i for i in range(1,4)] + 'reward_density': [0.25], # np.linspace(0.0, 1.0, num=5) + 'make_denser': [False], + 'terminal_state_density': [0.25], # np.linspace(0.1, 1.0, num=5) + 'transition_noise': [0],#, 0.01, 0.02, 0.10, 0.25] + 'reward_noise': [0],#, 1, 5, 10, 25] # Std dev. of normal dist. + 'dummy_seed': [i for i in range(num_seeds)], +}) + +var_configs = OrderedDict({ +"env": var_env_configs +}) + +env_config = { + "env": "RLToy-v0", + "horizon": 100, + "env_config": { + 'seed': 0, #seed + 'state_space_type': 'discrete', + 'action_space_type': 'discrete', + 'generate_random_mdp': True, + 'repeats_in_sequences': False, + 'reward_scale': 1.0, + 'completely_connected': True, + }, +} + +algorithm = "A3C" +agent_config = { + # Size of rollout batch + "sample_batch_size": 10, # maybe num_workers * sample_batch_size * num_envs_per_worker * grads_per_step + "train_batch_size": 100, # seems to have no effect + # Use PyTorch as backend - no LSTM support + "use_pytorch": False, + # GAE(gamma) parameter + "gamma": 0.99, + "lambda": 0.95, # + # Max global norm for each gradient calculated by worker + "grad_clip": 10.0, # low prio. + # Learning rate + "lr": 0.0001, # + # Learning rate schedule + "lr_schedule": None, + # Value Function Loss coefficient + "vf_loss_coeff": 0.1, # + # Entropy coefficient + "entropy_coeff": 0.1, # + # Min time per iteration + "min_iter_time_s": 0, + # Workers sample async. Note that this increases the effective + # sample_batch_size by up to 5x due to async buffering of batches. + "sample_async": True, + "timesteps_per_iteration": 1000, + "num_workers": 3, + "num_envs_per_worker": 5, + + "optimizer": { + "grads_per_step": 10 + }, +} + +model_config = { + "model": { + "fcnet_hiddens": [128, 128, 128], + "custom_preprocessor": "ohe", + "custom_options": {}, # extra options to pass to your preprocessor + "fcnet_activation": "tanh", + "use_lstm": False, + }, +} + +from ray import tune +eval_config = { + "evaluation_interval": 1, # I think this means every x training_iterations + "evaluation_config": { + "explore": False, + "exploration_fraction": 0, + "exploration_final_eps": 0, + "evaluation_num_episodes": 10, + "horizon": 100, + "env_config": { + "dummy_eval": True, #hack Used to check if we are in evaluation mode or training mode inside Ray callback on_episode_end() to be able to write eval stats + 'transition_noise': 0 if "state_space_type" in env_config["env_config"] and env_config["env_config"]["state_space_type"] == "discrete" else tune.function(lambda a: a.normal(0, 0)), + 'reward_noise': tune.function(lambda a: a.normal(0, 0)), + 'action_loss_weight': 0.0, + } + }, +} + +value_tuples = [] +for config_type, config_dict in var_configs.items(): + for key in config_dict: + assert type(var_configs[config_type][key]) == list, "var_config should be a dict of dicts with lists as the leaf values to allow each configuration option to take multiple possible values" + value_tuples.append(var_configs[config_type][key]) + +import itertools +cartesian_product_configs = list(itertools.product(*value_tuples)) +print("Total number of configs. to run:", len(cartesian_product_configs)) diff --git a/plot_experiments.ipynb b/plot_experiments.ipynb index 7fcaf50..aa4432a 100644 --- a/plot_experiments.ipynb +++ b/plot_experiments.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -15,11 +15,46 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": { "scrolled": true }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Loading data from a sequential run/already combined runs of experiment configurations.\n", + "Training stats read (rows, columns): (6000, 15)\n", + "train stats shape: (1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 10, 3)\n", + "train_aucs.shape: (1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 10, 3)\n", + "eval stats shape: (1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 10, 3)\n", + "eval_aucs.shape: (1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 10, 3)\n", + "Dimension varied: sequence_length . The values it took: ['1', '2', '3', '4'] . Number of values it took: 4 . Index in loaded data: 4\n", + "Loading data from a sequential run/already combined runs of experiment configurations.\n", + "Training stats read (rows, columns): (6000, 15)\n", + "train stats shape: (1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 10, 3)\n", + "train_aucs.shape: (1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 10, 3)\n", + "eval stats shape: (1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 10, 3)\n", + "eval_aucs.shape: (1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 10, 3)\n", + "Dimension varied: sequence_length . The values it took: ['1', '2', '3', '4'] . Number of values it took: 4 . Index in loaded data: 4\n", + "Loading data from a sequential run/already combined runs of experiment configurations.\n", + "Training stats read (rows, columns): (50000, 15)\n", + "train stats shape: (1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 10, 3)\n", + "train_aucs.shape: (1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 10, 3)\n", + "eval stats shape: (1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 10, 3)\n", + "eval_aucs.shape: (1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 10, 3)\n", + "Dimension varied: delay . The values it took: ['0', '1', '2', '4', '8'] . Number of values it took: 5 . Index in loaded data: 3\n", + "Loading data from a sequential run/already combined runs of experiment configurations.\n", + "Training stats read (rows, columns): (47650, 15)\n", + "train stats shape: (1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 10, 3)\n", + "train_aucs.shape: (1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 10, 3)\n", + "eval stats shape: (1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 10, 3)\n", + "eval_aucs.shape: (1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 10, 3)\n", + "Dimension varied: delay . The values it took: ['0', '1', '2', '4', '8'] . Number of values it took: 5 . Index in loaded data: 3\n" + ] + } + ], "source": [ "# Data loading\n", "mdpp_analysis = MDPP_Analysis()\n", @@ -30,31 +65,12 @@ "# For each experiment (also works in case of a single experiment):\n", "# Set exp_name to the name that was given to the experiment when running it, i.e., with the -e option\n", "# Set dir_name to the location where the CSV files from running an experiment were saved\n", + "files_dir = \"/mnt/484A4CAB4A4C9798/GoogleDrive/Maestria-Drive/HiWi/mdp_files\"\n", "experiments = {\n", - "# \"dqn_p_r_noises\" : \"/home/rajanr/spider_plots_data_discrete/\",\n", - "# \"a3c_p_r_noises\" : \"/home/rajanr/spider_plots_data_discrete/\",\n", - "# \"dqn_qbert_del\" :\"/home/rajanr/mdpp_8780992/\",\n", - "# \"rainbow_qbert_del\": \"/home/rajanr/mdpp_8815604\",\n", - "# \"a3c_qbert_del\": \"/home/rajanr/mdpp_3214031\",\n", - " \"td3_move_to_a_point_p_noise_target_radius\": \"/home/rajanr/mdpp_12707717_TD3_P_noise_target_radius\",\n", - " \"ddpg_move_to_a_point_p_noise\": \"/home/rajanr/mdpp_12680567_DDPG_P_noise\",\n", - " \"ddpg_move_to_a_point_r_noise\": \"/home/rajanr/mdpp_12700125_DDPG_R_Noise\",\n", - " \"ddpg_move_to_a_point_target_radius\": \"/home/rajanr/mdpp_12702414_DDPG_target_radius\",\n", - " \"ddpg_move_to_a_point_action_max\": \"/home/rajanr/mdpp_12703211_DDPG_action_max\",\n", - " \"ddpg_move_to_a_point_time_unit\": \"/home/rajanr/mdpp_12703537_DDPG_time_unit\",\n", - " \"ddpg_move_to_a_point_action_loss_weight\": \"/home/rajanr/mdpp_12705480_DDPG_action_loss_weight\",\n", - " \"ddpg_move_to_a_point_irr_dims\": \"/home/rajanr/mdpp_12713180_DDPG_irrelevant_features\",\n", - " \"td3_move_to_a_point_r_noise\": \"/home/rajanr/mdpp_12712031_TD3_R_noise\",\n", - " \"td3_move_to_a_point_action_max\": \"/home/rajanr/mdpp_12713006_TD3_action_max\",\n", - " \"td3_move_to_a_point_time_unit\": \"/home/rajanr/mdpp_12713385_TD3_time_unit\",\n", - " \"td3_move_to_a_point_action_loss_weight\": \"/home/rajanr/mdpp_12720811_TD3_action_loss_weight\",\n", - " \"td3_move_to_a_point_irr_dims\": \"/home/rajanr/mdpp_12721705_TD3_irrelevant_features\",\n", - " \"sac_move_to_a_point_p_noise_target_radius\": \"/home/rajanr/mdpp_12762946_SAC_P_noise_target_radius\",\n", - " \"sac_move_to_a_point_r_noise\": \"/home/rajanr/mdpp_12760692_SAC_R_Noise\",\n", - " \"sac_move_to_a_point_action_max\": \"/home/rajanr/mdpp_12746746_SAC_action_space_max\",\n", - " \"sac_move_to_a_point_time_unit\": \"/home/rajanr/mdpp_12747791_SAC_time_unit\",\n", - " \"sac_move_to_a_point_action_loss_weight\": \"/home/rajanr/mdpp_13090055_SAC_action_loss_weight\",\n", - " \"sac_move_to_a_point_irr_dims\": \"/home/rajanr/mdpp_12748228_SAC_irrelevant_features\", \n", + " \"a3c_seq\" : \"%s/a3c_seq/\"%files_dir,\n", + " \"a3c_lstm_seq\" : \"%s/a3c_lstm_seq/\"%files_dir,\n", + " \"a3c_del\" : \"%s/a3c_del/\"%files_dir,\n", + " \"a3c_lstm_del\" : \"%s/a3c_lstm_del/\"%files_dir,\n", "}\n", "\n", "# Remember to set load_eval=False in case evaluation stats were not recorded and only training stats were recorded, otherwise there will be errors in loading the data in this cell.\n", @@ -168,11 +184,4174 @@ "mdpp_analysis.plot_learning_curves(list_exp_data, save_fig, train=False)" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": false + }, + "outputs": [], + "source": [ + "weights = {}\n", + "weights['reward_noise'] = [.2, .2, .2, .2, .2, .0, .0, .0]\n", + "weights['action_loss_weight'] = [.33, .33, .33, .0, .0, .0]\n", + "\n", + "# Plot radar(spider) plot: Training: across different meta-features\n", + "mdpp_analysis.plot_radar(list_exp_data, save_fig, weights=weights)" + ] + }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], + "source": [ + "# Plot radar(spider) plot: Evaluation: across different meta-features\n", + "mdpp_analysis.plot_radar(list_exp_data, save_fig, train=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[1;31mLoading data from a sequential run/already combined runs of experiment configurations.\u001b[0;0m\n", + "../mdpp_to_cave/a3c_seq\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + "\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "
\n", + "
\n", + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
DefaultIncumbent
Quality-49.69-89.84
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/pimp/evaluator/local_parameter_importance.py:268: RuntimeWarning: invalid value encountered in double_scalars\n", + " overall_var_per_tree = {p : [t / sum_var_per_tree[idx] for idx, t in enumerate(trees)] for p, trees in\n", + "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/pimp/evaluator/local_parameter_importance.py:402: UserWarning: Attempted to set non-positive top ylim on a log-scaled axis.\n", + "Invalid limit will be ignored.\n", + " ax1.set_ylim([min_y * 0.95, max_y])\n" + ] + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "/* global mpl */\n", + "window.mpl = {};\n", + "\n", + "mpl.get_websocket_type = function () {\n", + " if (typeof WebSocket !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof MozWebSocket !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert(\n", + " 'Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.'\n", + " );\n", + " }\n", + "};\n", + "\n", + "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = this.ws.binaryType !== undefined;\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById('mpl-warnings');\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent =\n", + " 'This browser does not support binary websocket messages. ' +\n", + " 'Performance may be slow.';\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = document.createElement('div');\n", + " this.root.setAttribute('style', 'display: inline-block');\n", + " this._root_extra_style(this.root);\n", + "\n", + " parent_element.appendChild(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message('supports_binary', { value: fig.supports_binary });\n", + " fig.send_message('send_image_mode', {});\n", + " if (fig.ratio !== 1) {\n", + " fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n", + " }\n", + " fig.send_message('refresh', {});\n", + " };\n", + "\n", + " this.imageObj.onload = function () {\n", + " if (fig.image_mode === 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function () {\n", + " fig.ws.close();\n", + " };\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "};\n", + "\n", + "mpl.figure.prototype._init_header = function () {\n", + " var titlebar = document.createElement('div');\n", + " titlebar.classList =\n", + " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", + " var titletext = document.createElement('div');\n", + " titletext.classList = 'ui-dialog-title';\n", + " titletext.setAttribute(\n", + " 'style',\n", + " 'width: 100%; text-align: center; padding: 3px;'\n", + " );\n", + " titlebar.appendChild(titletext);\n", + " this.root.appendChild(titlebar);\n", + " this.header = titletext;\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._init_canvas = function () {\n", + " var fig = this;\n", + "\n", + " var canvas_div = (this.canvas_div = document.createElement('div'));\n", + " canvas_div.setAttribute(\n", + " 'style',\n", + " 'border: 1px solid #ddd;' +\n", + " 'box-sizing: content-box;' +\n", + " 'clear: both;' +\n", + " 'min-height: 1px;' +\n", + " 'min-width: 1px;' +\n", + " 'outline: 0;' +\n", + " 'overflow: hidden;' +\n", + " 'position: relative;' +\n", + " 'resize: both;'\n", + " );\n", + "\n", + " function on_keyboard_event_closure(name) {\n", + " return function (event) {\n", + " return fig.key_event(event, name);\n", + " };\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'keydown',\n", + " on_keyboard_event_closure('key_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'keyup',\n", + " on_keyboard_event_closure('key_release')\n", + " );\n", + "\n", + " this._canvas_extra_style(canvas_div);\n", + " this.root.appendChild(canvas_div);\n", + "\n", + " var canvas = (this.canvas = document.createElement('canvas'));\n", + " canvas.classList.add('mpl-canvas');\n", + " canvas.setAttribute('style', 'box-sizing: content-box;');\n", + "\n", + " this.context = canvas.getContext('2d');\n", + "\n", + " var backingStore =\n", + " this.context.backingStorePixelRatio ||\n", + " this.context.webkitBackingStorePixelRatio ||\n", + " this.context.mozBackingStorePixelRatio ||\n", + " this.context.msBackingStorePixelRatio ||\n", + " this.context.oBackingStorePixelRatio ||\n", + " this.context.backingStorePixelRatio ||\n", + " 1;\n", + "\n", + " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", + " 'canvas'\n", + " ));\n", + " rubberband_canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n", + " );\n", + "\n", + " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", + " if (this.ResizeObserver === undefined) {\n", + " if (window.ResizeObserver !== undefined) {\n", + " this.ResizeObserver = window.ResizeObserver;\n", + " } else {\n", + " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", + " this.ResizeObserver = obs.ResizeObserver;\n", + " }\n", + " }\n", + "\n", + " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", + " var nentries = entries.length;\n", + " for (var i = 0; i < nentries; i++) {\n", + " var entry = entries[i];\n", + " var width, height;\n", + " if (entry.contentBoxSize) {\n", + " if (entry.contentBoxSize instanceof Array) {\n", + " // Chrome 84 implements new version of spec.\n", + " width = entry.contentBoxSize[0].inlineSize;\n", + " height = entry.contentBoxSize[0].blockSize;\n", + " } else {\n", + " // Firefox implements old version of spec.\n", + " width = entry.contentBoxSize.inlineSize;\n", + " height = entry.contentBoxSize.blockSize;\n", + " }\n", + " } else {\n", + " // Chrome <84 implements even older version of spec.\n", + " width = entry.contentRect.width;\n", + " height = entry.contentRect.height;\n", + " }\n", + "\n", + " // Keep the size of the canvas and rubber band canvas in sync with\n", + " // the canvas container.\n", + " if (entry.devicePixelContentBoxSize) {\n", + " // Chrome 84 implements new version of spec.\n", + " canvas.setAttribute(\n", + " 'width',\n", + " entry.devicePixelContentBoxSize[0].inlineSize\n", + " );\n", + " canvas.setAttribute(\n", + " 'height',\n", + " entry.devicePixelContentBoxSize[0].blockSize\n", + " );\n", + " } else {\n", + " canvas.setAttribute('width', width * fig.ratio);\n", + " canvas.setAttribute('height', height * fig.ratio);\n", + " }\n", + " canvas.setAttribute(\n", + " 'style',\n", + " 'width: ' + width + 'px; height: ' + height + 'px;'\n", + " );\n", + "\n", + " rubberband_canvas.setAttribute('width', width);\n", + " rubberband_canvas.setAttribute('height', height);\n", + "\n", + " // And update the size in Python. We ignore the initial 0/0 size\n", + " // that occurs as the element is placed into the DOM, which should\n", + " // otherwise not happen due to the minimum size styling.\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", + " fig.request_resize(width, height);\n", + " }\n", + " }\n", + " });\n", + " this.resizeObserverInstance.observe(canvas_div);\n", + "\n", + " function on_mouse_event_closure(name) {\n", + " return function (event) {\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " }\n", + "\n", + " rubberband_canvas.addEventListener(\n", + " 'mousedown',\n", + " on_mouse_event_closure('button_press')\n", + " );\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseup',\n", + " on_mouse_event_closure('button_release')\n", + " );\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband_canvas.addEventListener(\n", + " 'mousemove',\n", + " on_mouse_event_closure('motion_notify')\n", + " );\n", + "\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseenter',\n", + " on_mouse_event_closure('figure_enter')\n", + " );\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseleave',\n", + " on_mouse_event_closure('figure_leave')\n", + " );\n", + "\n", + " canvas_div.addEventListener('wheel', function (event) {\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " on_mouse_event_closure('scroll')(event);\n", + " });\n", + "\n", + " canvas_div.appendChild(canvas);\n", + " canvas_div.appendChild(rubberband_canvas);\n", + "\n", + " this.rubberband_context = rubberband_canvas.getContext('2d');\n", + " this.rubberband_context.strokeStyle = '#000000';\n", + "\n", + " this._resize_canvas = function (width, height, forward) {\n", + " if (forward) {\n", + " canvas_div.style.width = width + 'px';\n", + " canvas_div.style.height = height + 'px';\n", + " }\n", + " };\n", + "\n", + " // Disable right mouse context menu.\n", + " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n", + " event.preventDefault();\n", + " return false;\n", + " });\n", + "\n", + " function set_focus() {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'mpl-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " continue;\n", + " }\n", + "\n", + " var button = (fig.buttons[name] = document.createElement('button'));\n", + " button.classList = 'mpl-widget';\n", + " button.setAttribute('role', 'button');\n", + " button.setAttribute('aria-disabled', 'false');\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + "\n", + " var icon_img = document.createElement('img');\n", + " icon_img.src = '_images/' + image + '.png';\n", + " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", + " icon_img.alt = tooltip;\n", + " button.appendChild(icon_img);\n", + "\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " var fmt_picker = document.createElement('select');\n", + " fmt_picker.classList = 'mpl-widget';\n", + " toolbar.appendChild(fmt_picker);\n", + " this.format_dropdown = fmt_picker;\n", + "\n", + " for (var ind in mpl.extensions) {\n", + " var fmt = mpl.extensions[ind];\n", + " var option = document.createElement('option');\n", + " option.selected = fmt === mpl.default_extension;\n", + " option.innerHTML = fmt;\n", + " fmt_picker.appendChild(option);\n", + " }\n", + "\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "};\n", + "\n", + "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", + " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", + " // which will in turn request a refresh of the image.\n", + " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", + "};\n", + "\n", + "mpl.figure.prototype.send_message = function (type, properties) {\n", + " properties['type'] = type;\n", + " properties['figure_id'] = this.id;\n", + " this.ws.send(JSON.stringify(properties));\n", + "};\n", + "\n", + "mpl.figure.prototype.send_draw_message = function () {\n", + " if (!this.waiting) {\n", + " this.waiting = true;\n", + " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " var format_dropdown = fig.format_dropdown;\n", + " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", + " fig.ondownload(fig, format);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", + " var size = msg['size'];\n", + " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", + " fig._resize_canvas(size[0], size[1], msg['forward']);\n", + " fig.send_message('refresh', {});\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", + " var x0 = msg['x0'] / fig.ratio;\n", + " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", + " var x1 = msg['x1'] / fig.ratio;\n", + " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", + " x0 = Math.floor(x0) + 0.5;\n", + " y0 = Math.floor(y0) + 0.5;\n", + " x1 = Math.floor(x1) + 0.5;\n", + " y1 = Math.floor(y1) + 0.5;\n", + " var min_x = Math.min(x0, x1);\n", + " var min_y = Math.min(y0, y1);\n", + " var width = Math.abs(x1 - x0);\n", + " var height = Math.abs(y1 - y0);\n", + "\n", + " fig.rubberband_context.clearRect(\n", + " 0,\n", + " 0,\n", + " fig.canvas.width / fig.ratio,\n", + " fig.canvas.height / fig.ratio\n", + " );\n", + "\n", + " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", + " // Updates the figure title.\n", + " fig.header.textContent = msg['label'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", + " var cursor = msg['cursor'];\n", + " switch (cursor) {\n", + " case 0:\n", + " cursor = 'pointer';\n", + " break;\n", + " case 1:\n", + " cursor = 'default';\n", + " break;\n", + " case 2:\n", + " cursor = 'crosshair';\n", + " break;\n", + " case 3:\n", + " cursor = 'move';\n", + " break;\n", + " }\n", + " fig.rubberband_canvas.style.cursor = cursor;\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_message = function (fig, msg) {\n", + " fig.message.textContent = msg['message'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", + " // Request the server to send over a new figure.\n", + " fig.send_draw_message();\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", + " fig.image_mode = msg['mode'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", + " for (var key in msg) {\n", + " if (!(key in fig.buttons)) {\n", + " continue;\n", + " }\n", + " fig.buttons[key].disabled = !msg[key];\n", + " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", + " if (msg['mode'] === 'PAN') {\n", + " fig.buttons['Pan'].classList.add('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " } else if (msg['mode'] === 'ZOOM') {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.add('active');\n", + " } else {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Called whenever the canvas gets updated.\n", + " this.send_message('ack', {});\n", + "};\n", + "\n", + "// A function to construct a web socket function for onmessage handling.\n", + "// Called in the figure constructor.\n", + "mpl.figure.prototype._make_on_message_function = function (fig) {\n", + " return function socket_on_message(evt) {\n", + " if (evt.data instanceof Blob) {\n", + " /* FIXME: We get \"Resource interpreted as Image but\n", + " * transferred with MIME type text/plain:\" errors on\n", + " * Chrome. But how to set the MIME type? It doesn't seem\n", + " * to be part of the websocket stream */\n", + " evt.data.type = 'image/png';\n", + "\n", + " /* Free the memory for the previous frames */\n", + " if (fig.imageObj.src) {\n", + " (window.URL || window.webkitURL).revokeObjectURL(\n", + " fig.imageObj.src\n", + " );\n", + " }\n", + "\n", + " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", + " evt.data\n", + " );\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " } else if (\n", + " typeof evt.data === 'string' &&\n", + " evt.data.slice(0, 21) === 'data:image/png;base64'\n", + " ) {\n", + " fig.imageObj.src = evt.data;\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " }\n", + "\n", + " var msg = JSON.parse(evt.data);\n", + " var msg_type = msg['type'];\n", + "\n", + " // Call the \"handle_{type}\" callback, which takes\n", + " // the figure and JSON message as its only arguments.\n", + " try {\n", + " var callback = fig['handle_' + msg_type];\n", + " } catch (e) {\n", + " console.log(\n", + " \"No handler for the '\" + msg_type + \"' message type: \",\n", + " msg\n", + " );\n", + " return;\n", + " }\n", + "\n", + " if (callback) {\n", + " try {\n", + " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", + " callback(fig, msg);\n", + " } catch (e) {\n", + " console.log(\n", + " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", + " e,\n", + " e.stack,\n", + " msg\n", + " );\n", + " }\n", + " }\n", + " };\n", + "};\n", + "\n", + "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", + "mpl.findpos = function (e) {\n", + " //this section is from http://www.quirksmode.org/js/events_properties.html\n", + " var targ;\n", + " if (!e) {\n", + " e = window.event;\n", + " }\n", + " if (e.target) {\n", + " targ = e.target;\n", + " } else if (e.srcElement) {\n", + " targ = e.srcElement;\n", + " }\n", + " if (targ.nodeType === 3) {\n", + " // defeat Safari bug\n", + " targ = targ.parentNode;\n", + " }\n", + "\n", + " // pageX,Y are the mouse positions relative to the document\n", + " var boundingRect = targ.getBoundingClientRect();\n", + " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n", + " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n", + "\n", + " return { x: x, y: y };\n", + "};\n", + "\n", + "/*\n", + " * return a copy of an object with only non-object keys\n", + " * we need this to avoid circular references\n", + " * http://stackoverflow.com/a/24161582/3208463\n", + " */\n", + "function simpleKeys(original) {\n", + " return Object.keys(original).reduce(function (obj, key) {\n", + " if (typeof original[key] !== 'object') {\n", + " obj[key] = original[key];\n", + " }\n", + " return obj;\n", + " }, {});\n", + "}\n", + "\n", + "mpl.figure.prototype.mouse_event = function (event, name) {\n", + " var canvas_pos = mpl.findpos(event);\n", + "\n", + " if (name === 'button_press') {\n", + " this.canvas.focus();\n", + " this.canvas_div.focus();\n", + " }\n", + "\n", + " var x = canvas_pos.x * this.ratio;\n", + " var y = canvas_pos.y * this.ratio;\n", + "\n", + " this.send_message(name, {\n", + " x: x,\n", + " y: y,\n", + " button: event.button,\n", + " step: event.step,\n", + " guiEvent: simpleKeys(event),\n", + " });\n", + "\n", + " /* This prevents the web browser from automatically changing to\n", + " * the text insertion cursor when the button is pressed. We want\n", + " * to control all of the cursor setting manually through the\n", + " * 'cursor' event from matplotlib */\n", + " event.preventDefault();\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", + " // Handle any extra behaviour associated with a key event\n", + "};\n", + "\n", + "mpl.figure.prototype.key_event = function (event, name) {\n", + " // Prevent repeat events\n", + " if (name === 'key_press') {\n", + " if (event.which === this._key) {\n", + " return;\n", + " } else {\n", + " this._key = event.which;\n", + " }\n", + " }\n", + " if (name === 'key_release') {\n", + " this._key = null;\n", + " }\n", + "\n", + " var value = '';\n", + " if (event.ctrlKey && event.which !== 17) {\n", + " value += 'ctrl+';\n", + " }\n", + " if (event.altKey && event.which !== 18) {\n", + " value += 'alt+';\n", + " }\n", + " if (event.shiftKey && event.which !== 16) {\n", + " value += 'shift+';\n", + " }\n", + "\n", + " value += 'k';\n", + " value += event.which.toString();\n", + "\n", + " this._key_event_extra(event, name);\n", + "\n", + " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", + " if (name === 'download') {\n", + " this.handle_save(this, null);\n", + " } else {\n", + " this.send_message('toolbar_button', { name: name });\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", + " this.message.textContent = tooltip;\n", + "};\n", + "\n", + "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", + "// prettier-ignore\n", + "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", + "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", + "\n", + "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", + "\n", + "mpl.default_extension = \"png\";/* global mpl */\n", + "\n", + "var comm_websocket_adapter = function (comm) {\n", + " // Create a \"websocket\"-like object which calls the given IPython comm\n", + " // object with the appropriate methods. Currently this is a non binary\n", + " // socket, so there is still some room for performance tuning.\n", + " var ws = {};\n", + "\n", + " ws.close = function () {\n", + " comm.close();\n", + " };\n", + " ws.send = function (m) {\n", + " //console.log('sending', m);\n", + " comm.send(m);\n", + " };\n", + " // Register the callback with on_msg.\n", + " comm.on_msg(function (msg) {\n", + " //console.log('receiving', msg['content']['data'], msg);\n", + " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", + " ws.onmessage(msg['content']['data']);\n", + " });\n", + " return ws;\n", + "};\n", + "\n", + "mpl.mpl_figure_comm = function (comm, msg) {\n", + " // This is the function which gets called when the mpl process\n", + " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", + "\n", + " var id = msg.content.data.id;\n", + " // Get hold of the div created by the display call when the Comm\n", + " // socket was opened in Python.\n", + " var element = document.getElementById(id);\n", + " var ws_proxy = comm_websocket_adapter(comm);\n", + "\n", + " function ondownload(figure, _format) {\n", + " window.open(figure.canvas.toDataURL());\n", + " }\n", + "\n", + " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", + "\n", + " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", + " // web socket which is closed, not our websocket->open comm proxy.\n", + " ws_proxy.onopen();\n", + "\n", + " fig.parent_element = element;\n", + " fig.cell_info = mpl.find_output_cell(\"
\");\n", + " if (!fig.cell_info) {\n", + " console.error('Failed to find cell for figure', id, fig);\n", + " return;\n", + " }\n", + " fig.cell_info[0].output_area.element.on(\n", + " 'cleared',\n", + " { fig: fig },\n", + " fig._remove_fig_handler\n", + " );\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_close = function (fig, msg) {\n", + " var width = fig.canvas.width / fig.ratio;\n", + " fig.cell_info[0].output_area.element.off(\n", + " 'cleared',\n", + " fig._remove_fig_handler\n", + " );\n", + " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", + "\n", + " // Update the output cell to use the data from the current canvas.\n", + " fig.push_to_output();\n", + " var dataURL = fig.canvas.toDataURL();\n", + " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", + " // the notebook keyboard shortcuts fail.\n", + " IPython.keyboard_manager.enable();\n", + " fig.parent_element.innerHTML =\n", + " '';\n", + " fig.close_ws(fig, msg);\n", + "};\n", + "\n", + "mpl.figure.prototype.close_ws = function (fig, msg) {\n", + " fig.send_message('closing', msg);\n", + " // fig.ws.close()\n", + "};\n", + "\n", + "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", + " // Turn the data on the canvas into data in the output cell.\n", + " var width = this.canvas.width / this.ratio;\n", + " var dataURL = this.canvas.toDataURL();\n", + " this.cell_info[1]['text/html'] =\n", + " '';\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Tell IPython that the notebook contents must change.\n", + " IPython.notebook.set_dirty(true);\n", + " this.send_message('ack', {});\n", + " var fig = this;\n", + " // Wait a second, then push the new image to the DOM so\n", + " // that it is saved nicely (might be nice to debounce this).\n", + " setTimeout(function () {\n", + " fig.push_to_output();\n", + " }, 1000);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'btn-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " var button;\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " continue;\n", + " }\n", + "\n", + " button = fig.buttons[name] = document.createElement('button');\n", + " button.classList = 'btn btn-default';\n", + " button.href = '#';\n", + " button.title = name;\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message pull-right';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = document.createElement('div');\n", + " buttongrp.classList = 'btn-group inline pull-right';\n", + " button = document.createElement('button');\n", + " button.classList = 'btn btn-mini btn-primary';\n", + " button.href = '#';\n", + " button.title = 'Stop Interaction';\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', function (_evt) {\n", + " fig.handle_close(fig, {});\n", + " });\n", + " button.addEventListener(\n", + " 'mouseover',\n", + " on_mouseover_closure('Stop Interaction')\n", + " );\n", + " buttongrp.appendChild(button);\n", + " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", + " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", + "};\n", + "\n", + "mpl.figure.prototype._remove_fig_handler = function (event) {\n", + " var fig = event.data.fig;\n", + " if (event.target !== this) {\n", + " // Ignore bubbled events from children.\n", + " return;\n", + " }\n", + " fig.close_ws(fig, {});\n", + "};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (el) {\n", + " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (el) {\n", + " // this is important to make the div 'focusable\n", + " el.setAttribute('tabindex', 0);\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " } else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager) {\n", + " manager = IPython.keyboard_manager;\n", + " }\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which === 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " fig.ondownload(fig, null);\n", + "};\n", + "\n", + "mpl.find_output_cell = function (html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i = 0; i < ncells; i++) {\n", + " var cell = cells[i];\n", + " if (cell.cell_type === 'code') {\n", + " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", + " var data = cell.output_area.outputs[j];\n", + " if (data.data) {\n", + " // IPython >= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] === html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "};\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel !== null) {\n", + " IPython.notebook.kernel.comm_manager.register_target(\n", + " 'matplotlib',\n", + " mpl.mpl_figure_comm\n", + " );\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[1;31mLoading data from a sequential run/already combined runs of experiment configurations.\u001b[0;0m\n", + "../mdpp_to_cave/a3c_lstm_seq\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + "\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "
\n", + "
\n", + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
DefaultIncumbent
Quality-24.37-88.06
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/pimp/evaluator/local_parameter_importance.py:268: RuntimeWarning: invalid value encountered in double_scalars\n", + " overall_var_per_tree = {p : [t / sum_var_per_tree[idx] for idx, t in enumerate(trees)] for p, trees in\n", + "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/pimp/evaluator/local_parameter_importance.py:402: UserWarning: Attempted to set non-positive top ylim on a log-scaled axis.\n", + "Invalid limit will be ignored.\n", + " ax1.set_ylim([min_y * 0.95, max_y])\n" + ] + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "/* global mpl */\n", + "window.mpl = {};\n", + "\n", + "mpl.get_websocket_type = function () {\n", + " if (typeof WebSocket !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof MozWebSocket !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert(\n", + " 'Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.'\n", + " );\n", + " }\n", + "};\n", + "\n", + "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = this.ws.binaryType !== undefined;\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById('mpl-warnings');\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent =\n", + " 'This browser does not support binary websocket messages. ' +\n", + " 'Performance may be slow.';\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = document.createElement('div');\n", + " this.root.setAttribute('style', 'display: inline-block');\n", + " this._root_extra_style(this.root);\n", + "\n", + " parent_element.appendChild(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message('supports_binary', { value: fig.supports_binary });\n", + " fig.send_message('send_image_mode', {});\n", + " if (fig.ratio !== 1) {\n", + " fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n", + " }\n", + " fig.send_message('refresh', {});\n", + " };\n", + "\n", + " this.imageObj.onload = function () {\n", + " if (fig.image_mode === 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function () {\n", + " fig.ws.close();\n", + " };\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "};\n", + "\n", + "mpl.figure.prototype._init_header = function () {\n", + " var titlebar = document.createElement('div');\n", + " titlebar.classList =\n", + " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", + " var titletext = document.createElement('div');\n", + " titletext.classList = 'ui-dialog-title';\n", + " titletext.setAttribute(\n", + " 'style',\n", + " 'width: 100%; text-align: center; padding: 3px;'\n", + " );\n", + " titlebar.appendChild(titletext);\n", + " this.root.appendChild(titlebar);\n", + " this.header = titletext;\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._init_canvas = function () {\n", + " var fig = this;\n", + "\n", + " var canvas_div = (this.canvas_div = document.createElement('div'));\n", + " canvas_div.setAttribute(\n", + " 'style',\n", + " 'border: 1px solid #ddd;' +\n", + " 'box-sizing: content-box;' +\n", + " 'clear: both;' +\n", + " 'min-height: 1px;' +\n", + " 'min-width: 1px;' +\n", + " 'outline: 0;' +\n", + " 'overflow: hidden;' +\n", + " 'position: relative;' +\n", + " 'resize: both;'\n", + " );\n", + "\n", + " function on_keyboard_event_closure(name) {\n", + " return function (event) {\n", + " return fig.key_event(event, name);\n", + " };\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'keydown',\n", + " on_keyboard_event_closure('key_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'keyup',\n", + " on_keyboard_event_closure('key_release')\n", + " );\n", + "\n", + " this._canvas_extra_style(canvas_div);\n", + " this.root.appendChild(canvas_div);\n", + "\n", + " var canvas = (this.canvas = document.createElement('canvas'));\n", + " canvas.classList.add('mpl-canvas');\n", + " canvas.setAttribute('style', 'box-sizing: content-box;');\n", + "\n", + " this.context = canvas.getContext('2d');\n", + "\n", + " var backingStore =\n", + " this.context.backingStorePixelRatio ||\n", + " this.context.webkitBackingStorePixelRatio ||\n", + " this.context.mozBackingStorePixelRatio ||\n", + " this.context.msBackingStorePixelRatio ||\n", + " this.context.oBackingStorePixelRatio ||\n", + " this.context.backingStorePixelRatio ||\n", + " 1;\n", + "\n", + " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", + " 'canvas'\n", + " ));\n", + " rubberband_canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n", + " );\n", + "\n", + " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", + " if (this.ResizeObserver === undefined) {\n", + " if (window.ResizeObserver !== undefined) {\n", + " this.ResizeObserver = window.ResizeObserver;\n", + " } else {\n", + " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", + " this.ResizeObserver = obs.ResizeObserver;\n", + " }\n", + " }\n", + "\n", + " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", + " var nentries = entries.length;\n", + " for (var i = 0; i < nentries; i++) {\n", + " var entry = entries[i];\n", + " var width, height;\n", + " if (entry.contentBoxSize) {\n", + " if (entry.contentBoxSize instanceof Array) {\n", + " // Chrome 84 implements new version of spec.\n", + " width = entry.contentBoxSize[0].inlineSize;\n", + " height = entry.contentBoxSize[0].blockSize;\n", + " } else {\n", + " // Firefox implements old version of spec.\n", + " width = entry.contentBoxSize.inlineSize;\n", + " height = entry.contentBoxSize.blockSize;\n", + " }\n", + " } else {\n", + " // Chrome <84 implements even older version of spec.\n", + " width = entry.contentRect.width;\n", + " height = entry.contentRect.height;\n", + " }\n", + "\n", + " // Keep the size of the canvas and rubber band canvas in sync with\n", + " // the canvas container.\n", + " if (entry.devicePixelContentBoxSize) {\n", + " // Chrome 84 implements new version of spec.\n", + " canvas.setAttribute(\n", + " 'width',\n", + " entry.devicePixelContentBoxSize[0].inlineSize\n", + " );\n", + " canvas.setAttribute(\n", + " 'height',\n", + " entry.devicePixelContentBoxSize[0].blockSize\n", + " );\n", + " } else {\n", + " canvas.setAttribute('width', width * fig.ratio);\n", + " canvas.setAttribute('height', height * fig.ratio);\n", + " }\n", + " canvas.setAttribute(\n", + " 'style',\n", + " 'width: ' + width + 'px; height: ' + height + 'px;'\n", + " );\n", + "\n", + " rubberband_canvas.setAttribute('width', width);\n", + " rubberband_canvas.setAttribute('height', height);\n", + "\n", + " // And update the size in Python. We ignore the initial 0/0 size\n", + " // that occurs as the element is placed into the DOM, which should\n", + " // otherwise not happen due to the minimum size styling.\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", + " fig.request_resize(width, height);\n", + " }\n", + " }\n", + " });\n", + " this.resizeObserverInstance.observe(canvas_div);\n", + "\n", + " function on_mouse_event_closure(name) {\n", + " return function (event) {\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " }\n", + "\n", + " rubberband_canvas.addEventListener(\n", + " 'mousedown',\n", + " on_mouse_event_closure('button_press')\n", + " );\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseup',\n", + " on_mouse_event_closure('button_release')\n", + " );\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband_canvas.addEventListener(\n", + " 'mousemove',\n", + " on_mouse_event_closure('motion_notify')\n", + " );\n", + "\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseenter',\n", + " on_mouse_event_closure('figure_enter')\n", + " );\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseleave',\n", + " on_mouse_event_closure('figure_leave')\n", + " );\n", + "\n", + " canvas_div.addEventListener('wheel', function (event) {\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " on_mouse_event_closure('scroll')(event);\n", + " });\n", + "\n", + " canvas_div.appendChild(canvas);\n", + " canvas_div.appendChild(rubberband_canvas);\n", + "\n", + " this.rubberband_context = rubberband_canvas.getContext('2d');\n", + " this.rubberband_context.strokeStyle = '#000000';\n", + "\n", + " this._resize_canvas = function (width, height, forward) {\n", + " if (forward) {\n", + " canvas_div.style.width = width + 'px';\n", + " canvas_div.style.height = height + 'px';\n", + " }\n", + " };\n", + "\n", + " // Disable right mouse context menu.\n", + " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n", + " event.preventDefault();\n", + " return false;\n", + " });\n", + "\n", + " function set_focus() {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'mpl-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " continue;\n", + " }\n", + "\n", + " var button = (fig.buttons[name] = document.createElement('button'));\n", + " button.classList = 'mpl-widget';\n", + " button.setAttribute('role', 'button');\n", + " button.setAttribute('aria-disabled', 'false');\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + "\n", + " var icon_img = document.createElement('img');\n", + " icon_img.src = '_images/' + image + '.png';\n", + " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", + " icon_img.alt = tooltip;\n", + " button.appendChild(icon_img);\n", + "\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " var fmt_picker = document.createElement('select');\n", + " fmt_picker.classList = 'mpl-widget';\n", + " toolbar.appendChild(fmt_picker);\n", + " this.format_dropdown = fmt_picker;\n", + "\n", + " for (var ind in mpl.extensions) {\n", + " var fmt = mpl.extensions[ind];\n", + " var option = document.createElement('option');\n", + " option.selected = fmt === mpl.default_extension;\n", + " option.innerHTML = fmt;\n", + " fmt_picker.appendChild(option);\n", + " }\n", + "\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "};\n", + "\n", + "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", + " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", + " // which will in turn request a refresh of the image.\n", + " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", + "};\n", + "\n", + "mpl.figure.prototype.send_message = function (type, properties) {\n", + " properties['type'] = type;\n", + " properties['figure_id'] = this.id;\n", + " this.ws.send(JSON.stringify(properties));\n", + "};\n", + "\n", + "mpl.figure.prototype.send_draw_message = function () {\n", + " if (!this.waiting) {\n", + " this.waiting = true;\n", + " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " var format_dropdown = fig.format_dropdown;\n", + " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", + " fig.ondownload(fig, format);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", + " var size = msg['size'];\n", + " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", + " fig._resize_canvas(size[0], size[1], msg['forward']);\n", + " fig.send_message('refresh', {});\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", + " var x0 = msg['x0'] / fig.ratio;\n", + " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", + " var x1 = msg['x1'] / fig.ratio;\n", + " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", + " x0 = Math.floor(x0) + 0.5;\n", + " y0 = Math.floor(y0) + 0.5;\n", + " x1 = Math.floor(x1) + 0.5;\n", + " y1 = Math.floor(y1) + 0.5;\n", + " var min_x = Math.min(x0, x1);\n", + " var min_y = Math.min(y0, y1);\n", + " var width = Math.abs(x1 - x0);\n", + " var height = Math.abs(y1 - y0);\n", + "\n", + " fig.rubberband_context.clearRect(\n", + " 0,\n", + " 0,\n", + " fig.canvas.width / fig.ratio,\n", + " fig.canvas.height / fig.ratio\n", + " );\n", + "\n", + " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", + " // Updates the figure title.\n", + " fig.header.textContent = msg['label'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", + " var cursor = msg['cursor'];\n", + " switch (cursor) {\n", + " case 0:\n", + " cursor = 'pointer';\n", + " break;\n", + " case 1:\n", + " cursor = 'default';\n", + " break;\n", + " case 2:\n", + " cursor = 'crosshair';\n", + " break;\n", + " case 3:\n", + " cursor = 'move';\n", + " break;\n", + " }\n", + " fig.rubberband_canvas.style.cursor = cursor;\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_message = function (fig, msg) {\n", + " fig.message.textContent = msg['message'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", + " // Request the server to send over a new figure.\n", + " fig.send_draw_message();\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", + " fig.image_mode = msg['mode'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", + " for (var key in msg) {\n", + " if (!(key in fig.buttons)) {\n", + " continue;\n", + " }\n", + " fig.buttons[key].disabled = !msg[key];\n", + " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", + " if (msg['mode'] === 'PAN') {\n", + " fig.buttons['Pan'].classList.add('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " } else if (msg['mode'] === 'ZOOM') {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.add('active');\n", + " } else {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Called whenever the canvas gets updated.\n", + " this.send_message('ack', {});\n", + "};\n", + "\n", + "// A function to construct a web socket function for onmessage handling.\n", + "// Called in the figure constructor.\n", + "mpl.figure.prototype._make_on_message_function = function (fig) {\n", + " return function socket_on_message(evt) {\n", + " if (evt.data instanceof Blob) {\n", + " /* FIXME: We get \"Resource interpreted as Image but\n", + " * transferred with MIME type text/plain:\" errors on\n", + " * Chrome. But how to set the MIME type? It doesn't seem\n", + " * to be part of the websocket stream */\n", + " evt.data.type = 'image/png';\n", + "\n", + " /* Free the memory for the previous frames */\n", + " if (fig.imageObj.src) {\n", + " (window.URL || window.webkitURL).revokeObjectURL(\n", + " fig.imageObj.src\n", + " );\n", + " }\n", + "\n", + " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", + " evt.data\n", + " );\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " } else if (\n", + " typeof evt.data === 'string' &&\n", + " evt.data.slice(0, 21) === 'data:image/png;base64'\n", + " ) {\n", + " fig.imageObj.src = evt.data;\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " }\n", + "\n", + " var msg = JSON.parse(evt.data);\n", + " var msg_type = msg['type'];\n", + "\n", + " // Call the \"handle_{type}\" callback, which takes\n", + " // the figure and JSON message as its only arguments.\n", + " try {\n", + " var callback = fig['handle_' + msg_type];\n", + " } catch (e) {\n", + " console.log(\n", + " \"No handler for the '\" + msg_type + \"' message type: \",\n", + " msg\n", + " );\n", + " return;\n", + " }\n", + "\n", + " if (callback) {\n", + " try {\n", + " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", + " callback(fig, msg);\n", + " } catch (e) {\n", + " console.log(\n", + " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", + " e,\n", + " e.stack,\n", + " msg\n", + " );\n", + " }\n", + " }\n", + " };\n", + "};\n", + "\n", + "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", + "mpl.findpos = function (e) {\n", + " //this section is from http://www.quirksmode.org/js/events_properties.html\n", + " var targ;\n", + " if (!e) {\n", + " e = window.event;\n", + " }\n", + " if (e.target) {\n", + " targ = e.target;\n", + " } else if (e.srcElement) {\n", + " targ = e.srcElement;\n", + " }\n", + " if (targ.nodeType === 3) {\n", + " // defeat Safari bug\n", + " targ = targ.parentNode;\n", + " }\n", + "\n", + " // pageX,Y are the mouse positions relative to the document\n", + " var boundingRect = targ.getBoundingClientRect();\n", + " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n", + " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n", + "\n", + " return { x: x, y: y };\n", + "};\n", + "\n", + "/*\n", + " * return a copy of an object with only non-object keys\n", + " * we need this to avoid circular references\n", + " * http://stackoverflow.com/a/24161582/3208463\n", + " */\n", + "function simpleKeys(original) {\n", + " return Object.keys(original).reduce(function (obj, key) {\n", + " if (typeof original[key] !== 'object') {\n", + " obj[key] = original[key];\n", + " }\n", + " return obj;\n", + " }, {});\n", + "}\n", + "\n", + "mpl.figure.prototype.mouse_event = function (event, name) {\n", + " var canvas_pos = mpl.findpos(event);\n", + "\n", + " if (name === 'button_press') {\n", + " this.canvas.focus();\n", + " this.canvas_div.focus();\n", + " }\n", + "\n", + " var x = canvas_pos.x * this.ratio;\n", + " var y = canvas_pos.y * this.ratio;\n", + "\n", + " this.send_message(name, {\n", + " x: x,\n", + " y: y,\n", + " button: event.button,\n", + " step: event.step,\n", + " guiEvent: simpleKeys(event),\n", + " });\n", + "\n", + " /* This prevents the web browser from automatically changing to\n", + " * the text insertion cursor when the button is pressed. We want\n", + " * to control all of the cursor setting manually through the\n", + " * 'cursor' event from matplotlib */\n", + " event.preventDefault();\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", + " // Handle any extra behaviour associated with a key event\n", + "};\n", + "\n", + "mpl.figure.prototype.key_event = function (event, name) {\n", + " // Prevent repeat events\n", + " if (name === 'key_press') {\n", + " if (event.which === this._key) {\n", + " return;\n", + " } else {\n", + " this._key = event.which;\n", + " }\n", + " }\n", + " if (name === 'key_release') {\n", + " this._key = null;\n", + " }\n", + "\n", + " var value = '';\n", + " if (event.ctrlKey && event.which !== 17) {\n", + " value += 'ctrl+';\n", + " }\n", + " if (event.altKey && event.which !== 18) {\n", + " value += 'alt+';\n", + " }\n", + " if (event.shiftKey && event.which !== 16) {\n", + " value += 'shift+';\n", + " }\n", + "\n", + " value += 'k';\n", + " value += event.which.toString();\n", + "\n", + " this._key_event_extra(event, name);\n", + "\n", + " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", + " if (name === 'download') {\n", + " this.handle_save(this, null);\n", + " } else {\n", + " this.send_message('toolbar_button', { name: name });\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", + " this.message.textContent = tooltip;\n", + "};\n", + "\n", + "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", + "// prettier-ignore\n", + "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", + "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", + "\n", + "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", + "\n", + "mpl.default_extension = \"png\";/* global mpl */\n", + "\n", + "var comm_websocket_adapter = function (comm) {\n", + " // Create a \"websocket\"-like object which calls the given IPython comm\n", + " // object with the appropriate methods. Currently this is a non binary\n", + " // socket, so there is still some room for performance tuning.\n", + " var ws = {};\n", + "\n", + " ws.close = function () {\n", + " comm.close();\n", + " };\n", + " ws.send = function (m) {\n", + " //console.log('sending', m);\n", + " comm.send(m);\n", + " };\n", + " // Register the callback with on_msg.\n", + " comm.on_msg(function (msg) {\n", + " //console.log('receiving', msg['content']['data'], msg);\n", + " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", + " ws.onmessage(msg['content']['data']);\n", + " });\n", + " return ws;\n", + "};\n", + "\n", + "mpl.mpl_figure_comm = function (comm, msg) {\n", + " // This is the function which gets called when the mpl process\n", + " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", + "\n", + " var id = msg.content.data.id;\n", + " // Get hold of the div created by the display call when the Comm\n", + " // socket was opened in Python.\n", + " var element = document.getElementById(id);\n", + " var ws_proxy = comm_websocket_adapter(comm);\n", + "\n", + " function ondownload(figure, _format) {\n", + " window.open(figure.canvas.toDataURL());\n", + " }\n", + "\n", + " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", + "\n", + " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", + " // web socket which is closed, not our websocket->open comm proxy.\n", + " ws_proxy.onopen();\n", + "\n", + " fig.parent_element = element;\n", + " fig.cell_info = mpl.find_output_cell(\"
\");\n", + " if (!fig.cell_info) {\n", + " console.error('Failed to find cell for figure', id, fig);\n", + " return;\n", + " }\n", + " fig.cell_info[0].output_area.element.on(\n", + " 'cleared',\n", + " { fig: fig },\n", + " fig._remove_fig_handler\n", + " );\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_close = function (fig, msg) {\n", + " var width = fig.canvas.width / fig.ratio;\n", + " fig.cell_info[0].output_area.element.off(\n", + " 'cleared',\n", + " fig._remove_fig_handler\n", + " );\n", + " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", + "\n", + " // Update the output cell to use the data from the current canvas.\n", + " fig.push_to_output();\n", + " var dataURL = fig.canvas.toDataURL();\n", + " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", + " // the notebook keyboard shortcuts fail.\n", + " IPython.keyboard_manager.enable();\n", + " fig.parent_element.innerHTML =\n", + " '';\n", + " fig.close_ws(fig, msg);\n", + "};\n", + "\n", + "mpl.figure.prototype.close_ws = function (fig, msg) {\n", + " fig.send_message('closing', msg);\n", + " // fig.ws.close()\n", + "};\n", + "\n", + "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", + " // Turn the data on the canvas into data in the output cell.\n", + " var width = this.canvas.width / this.ratio;\n", + " var dataURL = this.canvas.toDataURL();\n", + " this.cell_info[1]['text/html'] =\n", + " '';\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Tell IPython that the notebook contents must change.\n", + " IPython.notebook.set_dirty(true);\n", + " this.send_message('ack', {});\n", + " var fig = this;\n", + " // Wait a second, then push the new image to the DOM so\n", + " // that it is saved nicely (might be nice to debounce this).\n", + " setTimeout(function () {\n", + " fig.push_to_output();\n", + " }, 1000);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'btn-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " var button;\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " continue;\n", + " }\n", + "\n", + " button = fig.buttons[name] = document.createElement('button');\n", + " button.classList = 'btn btn-default';\n", + " button.href = '#';\n", + " button.title = name;\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message pull-right';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = document.createElement('div');\n", + " buttongrp.classList = 'btn-group inline pull-right';\n", + " button = document.createElement('button');\n", + " button.classList = 'btn btn-mini btn-primary';\n", + " button.href = '#';\n", + " button.title = 'Stop Interaction';\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', function (_evt) {\n", + " fig.handle_close(fig, {});\n", + " });\n", + " button.addEventListener(\n", + " 'mouseover',\n", + " on_mouseover_closure('Stop Interaction')\n", + " );\n", + " buttongrp.appendChild(button);\n", + " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", + " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", + "};\n", + "\n", + "mpl.figure.prototype._remove_fig_handler = function (event) {\n", + " var fig = event.data.fig;\n", + " if (event.target !== this) {\n", + " // Ignore bubbled events from children.\n", + " return;\n", + " }\n", + " fig.close_ws(fig, {});\n", + "};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (el) {\n", + " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (el) {\n", + " // this is important to make the div 'focusable\n", + " el.setAttribute('tabindex', 0);\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " } else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager) {\n", + " manager = IPython.keyboard_manager;\n", + " }\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which === 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " fig.ondownload(fig, null);\n", + "};\n", + "\n", + "mpl.find_output_cell = function (html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i = 0; i < ncells; i++) {\n", + " var cell = cells[i];\n", + " if (cell.cell_type === 'code') {\n", + " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", + " var data = cell.output_area.outputs[j];\n", + " if (data.data) {\n", + " // IPython >= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] === html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "};\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel !== null) {\n", + " IPython.notebook.kernel.comm_manager.register_target(\n", + " 'matplotlib',\n", + " mpl.mpl_figure_comm\n", + " );\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[1;31mLoading data from a sequential run/already combined runs of experiment configurations.\u001b[0;0m\n", + "../mdpp_to_cave/a3c_del\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + "\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "
\n", + "
\n", + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
DefaultIncumbent
Quality-90.19-98.51
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/pimp/evaluator/local_parameter_importance.py:268: RuntimeWarning: invalid value encountered in double_scalars\n", + " overall_var_per_tree = {p : [t / sum_var_per_tree[idx] for idx, t in enumerate(trees)] for p, trees in\n", + "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/pimp/evaluator/local_parameter_importance.py:402: UserWarning: Attempted to set non-positive top ylim on a log-scaled axis.\n", + "Invalid limit will be ignored.\n", + " ax1.set_ylim([min_y * 0.95, max_y])\n" + ] + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "/* global mpl */\n", + "window.mpl = {};\n", + "\n", + "mpl.get_websocket_type = function () {\n", + " if (typeof WebSocket !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof MozWebSocket !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert(\n", + " 'Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.'\n", + " );\n", + " }\n", + "};\n", + "\n", + "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = this.ws.binaryType !== undefined;\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById('mpl-warnings');\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent =\n", + " 'This browser does not support binary websocket messages. ' +\n", + " 'Performance may be slow.';\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = document.createElement('div');\n", + " this.root.setAttribute('style', 'display: inline-block');\n", + " this._root_extra_style(this.root);\n", + "\n", + " parent_element.appendChild(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message('supports_binary', { value: fig.supports_binary });\n", + " fig.send_message('send_image_mode', {});\n", + " if (fig.ratio !== 1) {\n", + " fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n", + " }\n", + " fig.send_message('refresh', {});\n", + " };\n", + "\n", + " this.imageObj.onload = function () {\n", + " if (fig.image_mode === 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function () {\n", + " fig.ws.close();\n", + " };\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "};\n", + "\n", + "mpl.figure.prototype._init_header = function () {\n", + " var titlebar = document.createElement('div');\n", + " titlebar.classList =\n", + " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", + " var titletext = document.createElement('div');\n", + " titletext.classList = 'ui-dialog-title';\n", + " titletext.setAttribute(\n", + " 'style',\n", + " 'width: 100%; text-align: center; padding: 3px;'\n", + " );\n", + " titlebar.appendChild(titletext);\n", + " this.root.appendChild(titlebar);\n", + " this.header = titletext;\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._init_canvas = function () {\n", + " var fig = this;\n", + "\n", + " var canvas_div = (this.canvas_div = document.createElement('div'));\n", + " canvas_div.setAttribute(\n", + " 'style',\n", + " 'border: 1px solid #ddd;' +\n", + " 'box-sizing: content-box;' +\n", + " 'clear: both;' +\n", + " 'min-height: 1px;' +\n", + " 'min-width: 1px;' +\n", + " 'outline: 0;' +\n", + " 'overflow: hidden;' +\n", + " 'position: relative;' +\n", + " 'resize: both;'\n", + " );\n", + "\n", + " function on_keyboard_event_closure(name) {\n", + " return function (event) {\n", + " return fig.key_event(event, name);\n", + " };\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'keydown',\n", + " on_keyboard_event_closure('key_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'keyup',\n", + " on_keyboard_event_closure('key_release')\n", + " );\n", + "\n", + " this._canvas_extra_style(canvas_div);\n", + " this.root.appendChild(canvas_div);\n", + "\n", + " var canvas = (this.canvas = document.createElement('canvas'));\n", + " canvas.classList.add('mpl-canvas');\n", + " canvas.setAttribute('style', 'box-sizing: content-box;');\n", + "\n", + " this.context = canvas.getContext('2d');\n", + "\n", + " var backingStore =\n", + " this.context.backingStorePixelRatio ||\n", + " this.context.webkitBackingStorePixelRatio ||\n", + " this.context.mozBackingStorePixelRatio ||\n", + " this.context.msBackingStorePixelRatio ||\n", + " this.context.oBackingStorePixelRatio ||\n", + " this.context.backingStorePixelRatio ||\n", + " 1;\n", + "\n", + " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", + " 'canvas'\n", + " ));\n", + " rubberband_canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n", + " );\n", + "\n", + " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", + " if (this.ResizeObserver === undefined) {\n", + " if (window.ResizeObserver !== undefined) {\n", + " this.ResizeObserver = window.ResizeObserver;\n", + " } else {\n", + " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", + " this.ResizeObserver = obs.ResizeObserver;\n", + " }\n", + " }\n", + "\n", + " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", + " var nentries = entries.length;\n", + " for (var i = 0; i < nentries; i++) {\n", + " var entry = entries[i];\n", + " var width, height;\n", + " if (entry.contentBoxSize) {\n", + " if (entry.contentBoxSize instanceof Array) {\n", + " // Chrome 84 implements new version of spec.\n", + " width = entry.contentBoxSize[0].inlineSize;\n", + " height = entry.contentBoxSize[0].blockSize;\n", + " } else {\n", + " // Firefox implements old version of spec.\n", + " width = entry.contentBoxSize.inlineSize;\n", + " height = entry.contentBoxSize.blockSize;\n", + " }\n", + " } else {\n", + " // Chrome <84 implements even older version of spec.\n", + " width = entry.contentRect.width;\n", + " height = entry.contentRect.height;\n", + " }\n", + "\n", + " // Keep the size of the canvas and rubber band canvas in sync with\n", + " // the canvas container.\n", + " if (entry.devicePixelContentBoxSize) {\n", + " // Chrome 84 implements new version of spec.\n", + " canvas.setAttribute(\n", + " 'width',\n", + " entry.devicePixelContentBoxSize[0].inlineSize\n", + " );\n", + " canvas.setAttribute(\n", + " 'height',\n", + " entry.devicePixelContentBoxSize[0].blockSize\n", + " );\n", + " } else {\n", + " canvas.setAttribute('width', width * fig.ratio);\n", + " canvas.setAttribute('height', height * fig.ratio);\n", + " }\n", + " canvas.setAttribute(\n", + " 'style',\n", + " 'width: ' + width + 'px; height: ' + height + 'px;'\n", + " );\n", + "\n", + " rubberband_canvas.setAttribute('width', width);\n", + " rubberband_canvas.setAttribute('height', height);\n", + "\n", + " // And update the size in Python. We ignore the initial 0/0 size\n", + " // that occurs as the element is placed into the DOM, which should\n", + " // otherwise not happen due to the minimum size styling.\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", + " fig.request_resize(width, height);\n", + " }\n", + " }\n", + " });\n", + " this.resizeObserverInstance.observe(canvas_div);\n", + "\n", + " function on_mouse_event_closure(name) {\n", + " return function (event) {\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " }\n", + "\n", + " rubberband_canvas.addEventListener(\n", + " 'mousedown',\n", + " on_mouse_event_closure('button_press')\n", + " );\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseup',\n", + " on_mouse_event_closure('button_release')\n", + " );\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband_canvas.addEventListener(\n", + " 'mousemove',\n", + " on_mouse_event_closure('motion_notify')\n", + " );\n", + "\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseenter',\n", + " on_mouse_event_closure('figure_enter')\n", + " );\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseleave',\n", + " on_mouse_event_closure('figure_leave')\n", + " );\n", + "\n", + " canvas_div.addEventListener('wheel', function (event) {\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " on_mouse_event_closure('scroll')(event);\n", + " });\n", + "\n", + " canvas_div.appendChild(canvas);\n", + " canvas_div.appendChild(rubberband_canvas);\n", + "\n", + " this.rubberband_context = rubberband_canvas.getContext('2d');\n", + " this.rubberband_context.strokeStyle = '#000000';\n", + "\n", + " this._resize_canvas = function (width, height, forward) {\n", + " if (forward) {\n", + " canvas_div.style.width = width + 'px';\n", + " canvas_div.style.height = height + 'px';\n", + " }\n", + " };\n", + "\n", + " // Disable right mouse context menu.\n", + " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n", + " event.preventDefault();\n", + " return false;\n", + " });\n", + "\n", + " function set_focus() {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'mpl-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " continue;\n", + " }\n", + "\n", + " var button = (fig.buttons[name] = document.createElement('button'));\n", + " button.classList = 'mpl-widget';\n", + " button.setAttribute('role', 'button');\n", + " button.setAttribute('aria-disabled', 'false');\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + "\n", + " var icon_img = document.createElement('img');\n", + " icon_img.src = '_images/' + image + '.png';\n", + " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", + " icon_img.alt = tooltip;\n", + " button.appendChild(icon_img);\n", + "\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " var fmt_picker = document.createElement('select');\n", + " fmt_picker.classList = 'mpl-widget';\n", + " toolbar.appendChild(fmt_picker);\n", + " this.format_dropdown = fmt_picker;\n", + "\n", + " for (var ind in mpl.extensions) {\n", + " var fmt = mpl.extensions[ind];\n", + " var option = document.createElement('option');\n", + " option.selected = fmt === mpl.default_extension;\n", + " option.innerHTML = fmt;\n", + " fmt_picker.appendChild(option);\n", + " }\n", + "\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "};\n", + "\n", + "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", + " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", + " // which will in turn request a refresh of the image.\n", + " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", + "};\n", + "\n", + "mpl.figure.prototype.send_message = function (type, properties) {\n", + " properties['type'] = type;\n", + " properties['figure_id'] = this.id;\n", + " this.ws.send(JSON.stringify(properties));\n", + "};\n", + "\n", + "mpl.figure.prototype.send_draw_message = function () {\n", + " if (!this.waiting) {\n", + " this.waiting = true;\n", + " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " var format_dropdown = fig.format_dropdown;\n", + " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", + " fig.ondownload(fig, format);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", + " var size = msg['size'];\n", + " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", + " fig._resize_canvas(size[0], size[1], msg['forward']);\n", + " fig.send_message('refresh', {});\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", + " var x0 = msg['x0'] / fig.ratio;\n", + " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", + " var x1 = msg['x1'] / fig.ratio;\n", + " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", + " x0 = Math.floor(x0) + 0.5;\n", + " y0 = Math.floor(y0) + 0.5;\n", + " x1 = Math.floor(x1) + 0.5;\n", + " y1 = Math.floor(y1) + 0.5;\n", + " var min_x = Math.min(x0, x1);\n", + " var min_y = Math.min(y0, y1);\n", + " var width = Math.abs(x1 - x0);\n", + " var height = Math.abs(y1 - y0);\n", + "\n", + " fig.rubberband_context.clearRect(\n", + " 0,\n", + " 0,\n", + " fig.canvas.width / fig.ratio,\n", + " fig.canvas.height / fig.ratio\n", + " );\n", + "\n", + " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", + " // Updates the figure title.\n", + " fig.header.textContent = msg['label'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", + " var cursor = msg['cursor'];\n", + " switch (cursor) {\n", + " case 0:\n", + " cursor = 'pointer';\n", + " break;\n", + " case 1:\n", + " cursor = 'default';\n", + " break;\n", + " case 2:\n", + " cursor = 'crosshair';\n", + " break;\n", + " case 3:\n", + " cursor = 'move';\n", + " break;\n", + " }\n", + " fig.rubberband_canvas.style.cursor = cursor;\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_message = function (fig, msg) {\n", + " fig.message.textContent = msg['message'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", + " // Request the server to send over a new figure.\n", + " fig.send_draw_message();\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", + " fig.image_mode = msg['mode'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", + " for (var key in msg) {\n", + " if (!(key in fig.buttons)) {\n", + " continue;\n", + " }\n", + " fig.buttons[key].disabled = !msg[key];\n", + " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", + " if (msg['mode'] === 'PAN') {\n", + " fig.buttons['Pan'].classList.add('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " } else if (msg['mode'] === 'ZOOM') {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.add('active');\n", + " } else {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Called whenever the canvas gets updated.\n", + " this.send_message('ack', {});\n", + "};\n", + "\n", + "// A function to construct a web socket function for onmessage handling.\n", + "// Called in the figure constructor.\n", + "mpl.figure.prototype._make_on_message_function = function (fig) {\n", + " return function socket_on_message(evt) {\n", + " if (evt.data instanceof Blob) {\n", + " /* FIXME: We get \"Resource interpreted as Image but\n", + " * transferred with MIME type text/plain:\" errors on\n", + " * Chrome. But how to set the MIME type? It doesn't seem\n", + " * to be part of the websocket stream */\n", + " evt.data.type = 'image/png';\n", + "\n", + " /* Free the memory for the previous frames */\n", + " if (fig.imageObj.src) {\n", + " (window.URL || window.webkitURL).revokeObjectURL(\n", + " fig.imageObj.src\n", + " );\n", + " }\n", + "\n", + " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", + " evt.data\n", + " );\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " } else if (\n", + " typeof evt.data === 'string' &&\n", + " evt.data.slice(0, 21) === 'data:image/png;base64'\n", + " ) {\n", + " fig.imageObj.src = evt.data;\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " }\n", + "\n", + " var msg = JSON.parse(evt.data);\n", + " var msg_type = msg['type'];\n", + "\n", + " // Call the \"handle_{type}\" callback, which takes\n", + " // the figure and JSON message as its only arguments.\n", + " try {\n", + " var callback = fig['handle_' + msg_type];\n", + " } catch (e) {\n", + " console.log(\n", + " \"No handler for the '\" + msg_type + \"' message type: \",\n", + " msg\n", + " );\n", + " return;\n", + " }\n", + "\n", + " if (callback) {\n", + " try {\n", + " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", + " callback(fig, msg);\n", + " } catch (e) {\n", + " console.log(\n", + " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", + " e,\n", + " e.stack,\n", + " msg\n", + " );\n", + " }\n", + " }\n", + " };\n", + "};\n", + "\n", + "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", + "mpl.findpos = function (e) {\n", + " //this section is from http://www.quirksmode.org/js/events_properties.html\n", + " var targ;\n", + " if (!e) {\n", + " e = window.event;\n", + " }\n", + " if (e.target) {\n", + " targ = e.target;\n", + " } else if (e.srcElement) {\n", + " targ = e.srcElement;\n", + " }\n", + " if (targ.nodeType === 3) {\n", + " // defeat Safari bug\n", + " targ = targ.parentNode;\n", + " }\n", + "\n", + " // pageX,Y are the mouse positions relative to the document\n", + " var boundingRect = targ.getBoundingClientRect();\n", + " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n", + " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n", + "\n", + " return { x: x, y: y };\n", + "};\n", + "\n", + "/*\n", + " * return a copy of an object with only non-object keys\n", + " * we need this to avoid circular references\n", + " * http://stackoverflow.com/a/24161582/3208463\n", + " */\n", + "function simpleKeys(original) {\n", + " return Object.keys(original).reduce(function (obj, key) {\n", + " if (typeof original[key] !== 'object') {\n", + " obj[key] = original[key];\n", + " }\n", + " return obj;\n", + " }, {});\n", + "}\n", + "\n", + "mpl.figure.prototype.mouse_event = function (event, name) {\n", + " var canvas_pos = mpl.findpos(event);\n", + "\n", + " if (name === 'button_press') {\n", + " this.canvas.focus();\n", + " this.canvas_div.focus();\n", + " }\n", + "\n", + " var x = canvas_pos.x * this.ratio;\n", + " var y = canvas_pos.y * this.ratio;\n", + "\n", + " this.send_message(name, {\n", + " x: x,\n", + " y: y,\n", + " button: event.button,\n", + " step: event.step,\n", + " guiEvent: simpleKeys(event),\n", + " });\n", + "\n", + " /* This prevents the web browser from automatically changing to\n", + " * the text insertion cursor when the button is pressed. We want\n", + " * to control all of the cursor setting manually through the\n", + " * 'cursor' event from matplotlib */\n", + " event.preventDefault();\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", + " // Handle any extra behaviour associated with a key event\n", + "};\n", + "\n", + "mpl.figure.prototype.key_event = function (event, name) {\n", + " // Prevent repeat events\n", + " if (name === 'key_press') {\n", + " if (event.which === this._key) {\n", + " return;\n", + " } else {\n", + " this._key = event.which;\n", + " }\n", + " }\n", + " if (name === 'key_release') {\n", + " this._key = null;\n", + " }\n", + "\n", + " var value = '';\n", + " if (event.ctrlKey && event.which !== 17) {\n", + " value += 'ctrl+';\n", + " }\n", + " if (event.altKey && event.which !== 18) {\n", + " value += 'alt+';\n", + " }\n", + " if (event.shiftKey && event.which !== 16) {\n", + " value += 'shift+';\n", + " }\n", + "\n", + " value += 'k';\n", + " value += event.which.toString();\n", + "\n", + " this._key_event_extra(event, name);\n", + "\n", + " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", + " if (name === 'download') {\n", + " this.handle_save(this, null);\n", + " } else {\n", + " this.send_message('toolbar_button', { name: name });\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", + " this.message.textContent = tooltip;\n", + "};\n", + "\n", + "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", + "// prettier-ignore\n", + "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", + "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", + "\n", + "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", + "\n", + "mpl.default_extension = \"png\";/* global mpl */\n", + "\n", + "var comm_websocket_adapter = function (comm) {\n", + " // Create a \"websocket\"-like object which calls the given IPython comm\n", + " // object with the appropriate methods. Currently this is a non binary\n", + " // socket, so there is still some room for performance tuning.\n", + " var ws = {};\n", + "\n", + " ws.close = function () {\n", + " comm.close();\n", + " };\n", + " ws.send = function (m) {\n", + " //console.log('sending', m);\n", + " comm.send(m);\n", + " };\n", + " // Register the callback with on_msg.\n", + " comm.on_msg(function (msg) {\n", + " //console.log('receiving', msg['content']['data'], msg);\n", + " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", + " ws.onmessage(msg['content']['data']);\n", + " });\n", + " return ws;\n", + "};\n", + "\n", + "mpl.mpl_figure_comm = function (comm, msg) {\n", + " // This is the function which gets called when the mpl process\n", + " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", + "\n", + " var id = msg.content.data.id;\n", + " // Get hold of the div created by the display call when the Comm\n", + " // socket was opened in Python.\n", + " var element = document.getElementById(id);\n", + " var ws_proxy = comm_websocket_adapter(comm);\n", + "\n", + " function ondownload(figure, _format) {\n", + " window.open(figure.canvas.toDataURL());\n", + " }\n", + "\n", + " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", + "\n", + " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", + " // web socket which is closed, not our websocket->open comm proxy.\n", + " ws_proxy.onopen();\n", + "\n", + " fig.parent_element = element;\n", + " fig.cell_info = mpl.find_output_cell(\"
\");\n", + " if (!fig.cell_info) {\n", + " console.error('Failed to find cell for figure', id, fig);\n", + " return;\n", + " }\n", + " fig.cell_info[0].output_area.element.on(\n", + " 'cleared',\n", + " { fig: fig },\n", + " fig._remove_fig_handler\n", + " );\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_close = function (fig, msg) {\n", + " var width = fig.canvas.width / fig.ratio;\n", + " fig.cell_info[0].output_area.element.off(\n", + " 'cleared',\n", + " fig._remove_fig_handler\n", + " );\n", + " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", + "\n", + " // Update the output cell to use the data from the current canvas.\n", + " fig.push_to_output();\n", + " var dataURL = fig.canvas.toDataURL();\n", + " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", + " // the notebook keyboard shortcuts fail.\n", + " IPython.keyboard_manager.enable();\n", + " fig.parent_element.innerHTML =\n", + " '';\n", + " fig.close_ws(fig, msg);\n", + "};\n", + "\n", + "mpl.figure.prototype.close_ws = function (fig, msg) {\n", + " fig.send_message('closing', msg);\n", + " // fig.ws.close()\n", + "};\n", + "\n", + "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", + " // Turn the data on the canvas into data in the output cell.\n", + " var width = this.canvas.width / this.ratio;\n", + " var dataURL = this.canvas.toDataURL();\n", + " this.cell_info[1]['text/html'] =\n", + " '';\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Tell IPython that the notebook contents must change.\n", + " IPython.notebook.set_dirty(true);\n", + " this.send_message('ack', {});\n", + " var fig = this;\n", + " // Wait a second, then push the new image to the DOM so\n", + " // that it is saved nicely (might be nice to debounce this).\n", + " setTimeout(function () {\n", + " fig.push_to_output();\n", + " }, 1000);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'btn-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " var button;\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " continue;\n", + " }\n", + "\n", + " button = fig.buttons[name] = document.createElement('button');\n", + " button.classList = 'btn btn-default';\n", + " button.href = '#';\n", + " button.title = name;\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message pull-right';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = document.createElement('div');\n", + " buttongrp.classList = 'btn-group inline pull-right';\n", + " button = document.createElement('button');\n", + " button.classList = 'btn btn-mini btn-primary';\n", + " button.href = '#';\n", + " button.title = 'Stop Interaction';\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', function (_evt) {\n", + " fig.handle_close(fig, {});\n", + " });\n", + " button.addEventListener(\n", + " 'mouseover',\n", + " on_mouseover_closure('Stop Interaction')\n", + " );\n", + " buttongrp.appendChild(button);\n", + " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", + " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", + "};\n", + "\n", + "mpl.figure.prototype._remove_fig_handler = function (event) {\n", + " var fig = event.data.fig;\n", + " if (event.target !== this) {\n", + " // Ignore bubbled events from children.\n", + " return;\n", + " }\n", + " fig.close_ws(fig, {});\n", + "};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (el) {\n", + " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (el) {\n", + " // this is important to make the div 'focusable\n", + " el.setAttribute('tabindex', 0);\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " } else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager) {\n", + " manager = IPython.keyboard_manager;\n", + " }\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which === 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " fig.ondownload(fig, null);\n", + "};\n", + "\n", + "mpl.find_output_cell = function (html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i = 0; i < ncells; i++) {\n", + " var cell = cells[i];\n", + " if (cell.cell_type === 'code') {\n", + " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", + " var data = cell.output_area.outputs[j];\n", + " if (data.data) {\n", + " // IPython >= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] === html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "};\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel !== null) {\n", + " IPython.notebook.kernel.comm_manager.register_target(\n", + " 'matplotlib',\n", + " mpl.mpl_figure_comm\n", + " );\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[1;31mLoading data from a sequential run/already combined runs of experiment configurations.\u001b[0;0m\n", + "../mdpp_to_cave/a3c_lstm_del\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + "\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "
\n", + "
\n", + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
DefaultIncumbent
Quality-83.95-96.01
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/pimp/evaluator/local_parameter_importance.py:268: RuntimeWarning: invalid value encountered in double_scalars\n", + " overall_var_per_tree = {p : [t / sum_var_per_tree[idx] for idx, t in enumerate(trees)] for p, trees in\n", + "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/pimp/evaluator/local_parameter_importance.py:402: UserWarning: Attempted to set non-positive top ylim on a log-scaled axis.\n", + "Invalid limit will be ignored.\n", + " ax1.set_ylim([min_y * 0.95, max_y])\n" + ] + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "/* global mpl */\n", + "window.mpl = {};\n", + "\n", + "mpl.get_websocket_type = function () {\n", + " if (typeof WebSocket !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof MozWebSocket !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert(\n", + " 'Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.'\n", + " );\n", + " }\n", + "};\n", + "\n", + "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = this.ws.binaryType !== undefined;\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById('mpl-warnings');\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent =\n", + " 'This browser does not support binary websocket messages. ' +\n", + " 'Performance may be slow.';\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = document.createElement('div');\n", + " this.root.setAttribute('style', 'display: inline-block');\n", + " this._root_extra_style(this.root);\n", + "\n", + " parent_element.appendChild(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message('supports_binary', { value: fig.supports_binary });\n", + " fig.send_message('send_image_mode', {});\n", + " if (fig.ratio !== 1) {\n", + " fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n", + " }\n", + " fig.send_message('refresh', {});\n", + " };\n", + "\n", + " this.imageObj.onload = function () {\n", + " if (fig.image_mode === 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function () {\n", + " fig.ws.close();\n", + " };\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "};\n", + "\n", + "mpl.figure.prototype._init_header = function () {\n", + " var titlebar = document.createElement('div');\n", + " titlebar.classList =\n", + " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", + " var titletext = document.createElement('div');\n", + " titletext.classList = 'ui-dialog-title';\n", + " titletext.setAttribute(\n", + " 'style',\n", + " 'width: 100%; text-align: center; padding: 3px;'\n", + " );\n", + " titlebar.appendChild(titletext);\n", + " this.root.appendChild(titlebar);\n", + " this.header = titletext;\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._init_canvas = function () {\n", + " var fig = this;\n", + "\n", + " var canvas_div = (this.canvas_div = document.createElement('div'));\n", + " canvas_div.setAttribute(\n", + " 'style',\n", + " 'border: 1px solid #ddd;' +\n", + " 'box-sizing: content-box;' +\n", + " 'clear: both;' +\n", + " 'min-height: 1px;' +\n", + " 'min-width: 1px;' +\n", + " 'outline: 0;' +\n", + " 'overflow: hidden;' +\n", + " 'position: relative;' +\n", + " 'resize: both;'\n", + " );\n", + "\n", + " function on_keyboard_event_closure(name) {\n", + " return function (event) {\n", + " return fig.key_event(event, name);\n", + " };\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'keydown',\n", + " on_keyboard_event_closure('key_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'keyup',\n", + " on_keyboard_event_closure('key_release')\n", + " );\n", + "\n", + " this._canvas_extra_style(canvas_div);\n", + " this.root.appendChild(canvas_div);\n", + "\n", + " var canvas = (this.canvas = document.createElement('canvas'));\n", + " canvas.classList.add('mpl-canvas');\n", + " canvas.setAttribute('style', 'box-sizing: content-box;');\n", + "\n", + " this.context = canvas.getContext('2d');\n", + "\n", + " var backingStore =\n", + " this.context.backingStorePixelRatio ||\n", + " this.context.webkitBackingStorePixelRatio ||\n", + " this.context.mozBackingStorePixelRatio ||\n", + " this.context.msBackingStorePixelRatio ||\n", + " this.context.oBackingStorePixelRatio ||\n", + " this.context.backingStorePixelRatio ||\n", + " 1;\n", + "\n", + " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", + " 'canvas'\n", + " ));\n", + " rubberband_canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n", + " );\n", + "\n", + " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", + " if (this.ResizeObserver === undefined) {\n", + " if (window.ResizeObserver !== undefined) {\n", + " this.ResizeObserver = window.ResizeObserver;\n", + " } else {\n", + " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", + " this.ResizeObserver = obs.ResizeObserver;\n", + " }\n", + " }\n", + "\n", + " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", + " var nentries = entries.length;\n", + " for (var i = 0; i < nentries; i++) {\n", + " var entry = entries[i];\n", + " var width, height;\n", + " if (entry.contentBoxSize) {\n", + " if (entry.contentBoxSize instanceof Array) {\n", + " // Chrome 84 implements new version of spec.\n", + " width = entry.contentBoxSize[0].inlineSize;\n", + " height = entry.contentBoxSize[0].blockSize;\n", + " } else {\n", + " // Firefox implements old version of spec.\n", + " width = entry.contentBoxSize.inlineSize;\n", + " height = entry.contentBoxSize.blockSize;\n", + " }\n", + " } else {\n", + " // Chrome <84 implements even older version of spec.\n", + " width = entry.contentRect.width;\n", + " height = entry.contentRect.height;\n", + " }\n", + "\n", + " // Keep the size of the canvas and rubber band canvas in sync with\n", + " // the canvas container.\n", + " if (entry.devicePixelContentBoxSize) {\n", + " // Chrome 84 implements new version of spec.\n", + " canvas.setAttribute(\n", + " 'width',\n", + " entry.devicePixelContentBoxSize[0].inlineSize\n", + " );\n", + " canvas.setAttribute(\n", + " 'height',\n", + " entry.devicePixelContentBoxSize[0].blockSize\n", + " );\n", + " } else {\n", + " canvas.setAttribute('width', width * fig.ratio);\n", + " canvas.setAttribute('height', height * fig.ratio);\n", + " }\n", + " canvas.setAttribute(\n", + " 'style',\n", + " 'width: ' + width + 'px; height: ' + height + 'px;'\n", + " );\n", + "\n", + " rubberband_canvas.setAttribute('width', width);\n", + " rubberband_canvas.setAttribute('height', height);\n", + "\n", + " // And update the size in Python. We ignore the initial 0/0 size\n", + " // that occurs as the element is placed into the DOM, which should\n", + " // otherwise not happen due to the minimum size styling.\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", + " fig.request_resize(width, height);\n", + " }\n", + " }\n", + " });\n", + " this.resizeObserverInstance.observe(canvas_div);\n", + "\n", + " function on_mouse_event_closure(name) {\n", + " return function (event) {\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " }\n", + "\n", + " rubberband_canvas.addEventListener(\n", + " 'mousedown',\n", + " on_mouse_event_closure('button_press')\n", + " );\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseup',\n", + " on_mouse_event_closure('button_release')\n", + " );\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband_canvas.addEventListener(\n", + " 'mousemove',\n", + " on_mouse_event_closure('motion_notify')\n", + " );\n", + "\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseenter',\n", + " on_mouse_event_closure('figure_enter')\n", + " );\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseleave',\n", + " on_mouse_event_closure('figure_leave')\n", + " );\n", + "\n", + " canvas_div.addEventListener('wheel', function (event) {\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " on_mouse_event_closure('scroll')(event);\n", + " });\n", + "\n", + " canvas_div.appendChild(canvas);\n", + " canvas_div.appendChild(rubberband_canvas);\n", + "\n", + " this.rubberband_context = rubberband_canvas.getContext('2d');\n", + " this.rubberband_context.strokeStyle = '#000000';\n", + "\n", + " this._resize_canvas = function (width, height, forward) {\n", + " if (forward) {\n", + " canvas_div.style.width = width + 'px';\n", + " canvas_div.style.height = height + 'px';\n", + " }\n", + " };\n", + "\n", + " // Disable right mouse context menu.\n", + " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n", + " event.preventDefault();\n", + " return false;\n", + " });\n", + "\n", + " function set_focus() {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'mpl-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " continue;\n", + " }\n", + "\n", + " var button = (fig.buttons[name] = document.createElement('button'));\n", + " button.classList = 'mpl-widget';\n", + " button.setAttribute('role', 'button');\n", + " button.setAttribute('aria-disabled', 'false');\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + "\n", + " var icon_img = document.createElement('img');\n", + " icon_img.src = '_images/' + image + '.png';\n", + " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", + " icon_img.alt = tooltip;\n", + " button.appendChild(icon_img);\n", + "\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " var fmt_picker = document.createElement('select');\n", + " fmt_picker.classList = 'mpl-widget';\n", + " toolbar.appendChild(fmt_picker);\n", + " this.format_dropdown = fmt_picker;\n", + "\n", + " for (var ind in mpl.extensions) {\n", + " var fmt = mpl.extensions[ind];\n", + " var option = document.createElement('option');\n", + " option.selected = fmt === mpl.default_extension;\n", + " option.innerHTML = fmt;\n", + " fmt_picker.appendChild(option);\n", + " }\n", + "\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "};\n", + "\n", + "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", + " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", + " // which will in turn request a refresh of the image.\n", + " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", + "};\n", + "\n", + "mpl.figure.prototype.send_message = function (type, properties) {\n", + " properties['type'] = type;\n", + " properties['figure_id'] = this.id;\n", + " this.ws.send(JSON.stringify(properties));\n", + "};\n", + "\n", + "mpl.figure.prototype.send_draw_message = function () {\n", + " if (!this.waiting) {\n", + " this.waiting = true;\n", + " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " var format_dropdown = fig.format_dropdown;\n", + " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", + " fig.ondownload(fig, format);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", + " var size = msg['size'];\n", + " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", + " fig._resize_canvas(size[0], size[1], msg['forward']);\n", + " fig.send_message('refresh', {});\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", + " var x0 = msg['x0'] / fig.ratio;\n", + " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", + " var x1 = msg['x1'] / fig.ratio;\n", + " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", + " x0 = Math.floor(x0) + 0.5;\n", + " y0 = Math.floor(y0) + 0.5;\n", + " x1 = Math.floor(x1) + 0.5;\n", + " y1 = Math.floor(y1) + 0.5;\n", + " var min_x = Math.min(x0, x1);\n", + " var min_y = Math.min(y0, y1);\n", + " var width = Math.abs(x1 - x0);\n", + " var height = Math.abs(y1 - y0);\n", + "\n", + " fig.rubberband_context.clearRect(\n", + " 0,\n", + " 0,\n", + " fig.canvas.width / fig.ratio,\n", + " fig.canvas.height / fig.ratio\n", + " );\n", + "\n", + " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", + " // Updates the figure title.\n", + " fig.header.textContent = msg['label'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", + " var cursor = msg['cursor'];\n", + " switch (cursor) {\n", + " case 0:\n", + " cursor = 'pointer';\n", + " break;\n", + " case 1:\n", + " cursor = 'default';\n", + " break;\n", + " case 2:\n", + " cursor = 'crosshair';\n", + " break;\n", + " case 3:\n", + " cursor = 'move';\n", + " break;\n", + " }\n", + " fig.rubberband_canvas.style.cursor = cursor;\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_message = function (fig, msg) {\n", + " fig.message.textContent = msg['message'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", + " // Request the server to send over a new figure.\n", + " fig.send_draw_message();\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", + " fig.image_mode = msg['mode'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", + " for (var key in msg) {\n", + " if (!(key in fig.buttons)) {\n", + " continue;\n", + " }\n", + " fig.buttons[key].disabled = !msg[key];\n", + " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", + " if (msg['mode'] === 'PAN') {\n", + " fig.buttons['Pan'].classList.add('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " } else if (msg['mode'] === 'ZOOM') {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.add('active');\n", + " } else {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Called whenever the canvas gets updated.\n", + " this.send_message('ack', {});\n", + "};\n", + "\n", + "// A function to construct a web socket function for onmessage handling.\n", + "// Called in the figure constructor.\n", + "mpl.figure.prototype._make_on_message_function = function (fig) {\n", + " return function socket_on_message(evt) {\n", + " if (evt.data instanceof Blob) {\n", + " /* FIXME: We get \"Resource interpreted as Image but\n", + " * transferred with MIME type text/plain:\" errors on\n", + " * Chrome. But how to set the MIME type? It doesn't seem\n", + " * to be part of the websocket stream */\n", + " evt.data.type = 'image/png';\n", + "\n", + " /* Free the memory for the previous frames */\n", + " if (fig.imageObj.src) {\n", + " (window.URL || window.webkitURL).revokeObjectURL(\n", + " fig.imageObj.src\n", + " );\n", + " }\n", + "\n", + " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", + " evt.data\n", + " );\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " } else if (\n", + " typeof evt.data === 'string' &&\n", + " evt.data.slice(0, 21) === 'data:image/png;base64'\n", + " ) {\n", + " fig.imageObj.src = evt.data;\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " }\n", + "\n", + " var msg = JSON.parse(evt.data);\n", + " var msg_type = msg['type'];\n", + "\n", + " // Call the \"handle_{type}\" callback, which takes\n", + " // the figure and JSON message as its only arguments.\n", + " try {\n", + " var callback = fig['handle_' + msg_type];\n", + " } catch (e) {\n", + " console.log(\n", + " \"No handler for the '\" + msg_type + \"' message type: \",\n", + " msg\n", + " );\n", + " return;\n", + " }\n", + "\n", + " if (callback) {\n", + " try {\n", + " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", + " callback(fig, msg);\n", + " } catch (e) {\n", + " console.log(\n", + " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", + " e,\n", + " e.stack,\n", + " msg\n", + " );\n", + " }\n", + " }\n", + " };\n", + "};\n", + "\n", + "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", + "mpl.findpos = function (e) {\n", + " //this section is from http://www.quirksmode.org/js/events_properties.html\n", + " var targ;\n", + " if (!e) {\n", + " e = window.event;\n", + " }\n", + " if (e.target) {\n", + " targ = e.target;\n", + " } else if (e.srcElement) {\n", + " targ = e.srcElement;\n", + " }\n", + " if (targ.nodeType === 3) {\n", + " // defeat Safari bug\n", + " targ = targ.parentNode;\n", + " }\n", + "\n", + " // pageX,Y are the mouse positions relative to the document\n", + " var boundingRect = targ.getBoundingClientRect();\n", + " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n", + " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n", + "\n", + " return { x: x, y: y };\n", + "};\n", + "\n", + "/*\n", + " * return a copy of an object with only non-object keys\n", + " * we need this to avoid circular references\n", + " * http://stackoverflow.com/a/24161582/3208463\n", + " */\n", + "function simpleKeys(original) {\n", + " return Object.keys(original).reduce(function (obj, key) {\n", + " if (typeof original[key] !== 'object') {\n", + " obj[key] = original[key];\n", + " }\n", + " return obj;\n", + " }, {});\n", + "}\n", + "\n", + "mpl.figure.prototype.mouse_event = function (event, name) {\n", + " var canvas_pos = mpl.findpos(event);\n", + "\n", + " if (name === 'button_press') {\n", + " this.canvas.focus();\n", + " this.canvas_div.focus();\n", + " }\n", + "\n", + " var x = canvas_pos.x * this.ratio;\n", + " var y = canvas_pos.y * this.ratio;\n", + "\n", + " this.send_message(name, {\n", + " x: x,\n", + " y: y,\n", + " button: event.button,\n", + " step: event.step,\n", + " guiEvent: simpleKeys(event),\n", + " });\n", + "\n", + " /* This prevents the web browser from automatically changing to\n", + " * the text insertion cursor when the button is pressed. We want\n", + " * to control all of the cursor setting manually through the\n", + " * 'cursor' event from matplotlib */\n", + " event.preventDefault();\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", + " // Handle any extra behaviour associated with a key event\n", + "};\n", + "\n", + "mpl.figure.prototype.key_event = function (event, name) {\n", + " // Prevent repeat events\n", + " if (name === 'key_press') {\n", + " if (event.which === this._key) {\n", + " return;\n", + " } else {\n", + " this._key = event.which;\n", + " }\n", + " }\n", + " if (name === 'key_release') {\n", + " this._key = null;\n", + " }\n", + "\n", + " var value = '';\n", + " if (event.ctrlKey && event.which !== 17) {\n", + " value += 'ctrl+';\n", + " }\n", + " if (event.altKey && event.which !== 18) {\n", + " value += 'alt+';\n", + " }\n", + " if (event.shiftKey && event.which !== 16) {\n", + " value += 'shift+';\n", + " }\n", + "\n", + " value += 'k';\n", + " value += event.which.toString();\n", + "\n", + " this._key_event_extra(event, name);\n", + "\n", + " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", + " if (name === 'download') {\n", + " this.handle_save(this, null);\n", + " } else {\n", + " this.send_message('toolbar_button', { name: name });\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", + " this.message.textContent = tooltip;\n", + "};\n", + "\n", + "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", + "// prettier-ignore\n", + "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", + "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", + "\n", + "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", + "\n", + "mpl.default_extension = \"png\";/* global mpl */\n", + "\n", + "var comm_websocket_adapter = function (comm) {\n", + " // Create a \"websocket\"-like object which calls the given IPython comm\n", + " // object with the appropriate methods. Currently this is a non binary\n", + " // socket, so there is still some room for performance tuning.\n", + " var ws = {};\n", + "\n", + " ws.close = function () {\n", + " comm.close();\n", + " };\n", + " ws.send = function (m) {\n", + " //console.log('sending', m);\n", + " comm.send(m);\n", + " };\n", + " // Register the callback with on_msg.\n", + " comm.on_msg(function (msg) {\n", + " //console.log('receiving', msg['content']['data'], msg);\n", + " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", + " ws.onmessage(msg['content']['data']);\n", + " });\n", + " return ws;\n", + "};\n", + "\n", + "mpl.mpl_figure_comm = function (comm, msg) {\n", + " // This is the function which gets called when the mpl process\n", + " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", + "\n", + " var id = msg.content.data.id;\n", + " // Get hold of the div created by the display call when the Comm\n", + " // socket was opened in Python.\n", + " var element = document.getElementById(id);\n", + " var ws_proxy = comm_websocket_adapter(comm);\n", + "\n", + " function ondownload(figure, _format) {\n", + " window.open(figure.canvas.toDataURL());\n", + " }\n", + "\n", + " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", + "\n", + " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", + " // web socket which is closed, not our websocket->open comm proxy.\n", + " ws_proxy.onopen();\n", + "\n", + " fig.parent_element = element;\n", + " fig.cell_info = mpl.find_output_cell(\"
\");\n", + " if (!fig.cell_info) {\n", + " console.error('Failed to find cell for figure', id, fig);\n", + " return;\n", + " }\n", + " fig.cell_info[0].output_area.element.on(\n", + " 'cleared',\n", + " { fig: fig },\n", + " fig._remove_fig_handler\n", + " );\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_close = function (fig, msg) {\n", + " var width = fig.canvas.width / fig.ratio;\n", + " fig.cell_info[0].output_area.element.off(\n", + " 'cleared',\n", + " fig._remove_fig_handler\n", + " );\n", + " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", + "\n", + " // Update the output cell to use the data from the current canvas.\n", + " fig.push_to_output();\n", + " var dataURL = fig.canvas.toDataURL();\n", + " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", + " // the notebook keyboard shortcuts fail.\n", + " IPython.keyboard_manager.enable();\n", + " fig.parent_element.innerHTML =\n", + " '';\n", + " fig.close_ws(fig, msg);\n", + "};\n", + "\n", + "mpl.figure.prototype.close_ws = function (fig, msg) {\n", + " fig.send_message('closing', msg);\n", + " // fig.ws.close()\n", + "};\n", + "\n", + "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", + " // Turn the data on the canvas into data in the output cell.\n", + " var width = this.canvas.width / this.ratio;\n", + " var dataURL = this.canvas.toDataURL();\n", + " this.cell_info[1]['text/html'] =\n", + " '';\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Tell IPython that the notebook contents must change.\n", + " IPython.notebook.set_dirty(true);\n", + " this.send_message('ack', {});\n", + " var fig = this;\n", + " // Wait a second, then push the new image to the DOM so\n", + " // that it is saved nicely (might be nice to debounce this).\n", + " setTimeout(function () {\n", + " fig.push_to_output();\n", + " }, 1000);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'btn-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " var button;\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " continue;\n", + " }\n", + "\n", + " button = fig.buttons[name] = document.createElement('button');\n", + " button.classList = 'btn btn-default';\n", + " button.href = '#';\n", + " button.title = name;\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message pull-right';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = document.createElement('div');\n", + " buttongrp.classList = 'btn-group inline pull-right';\n", + " button = document.createElement('button');\n", + " button.classList = 'btn btn-mini btn-primary';\n", + " button.href = '#';\n", + " button.title = 'Stop Interaction';\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', function (_evt) {\n", + " fig.handle_close(fig, {});\n", + " });\n", + " button.addEventListener(\n", + " 'mouseover',\n", + " on_mouseover_closure('Stop Interaction')\n", + " );\n", + " buttongrp.appendChild(button);\n", + " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", + " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", + "};\n", + "\n", + "mpl.figure.prototype._remove_fig_handler = function (event) {\n", + " var fig = event.data.fig;\n", + " if (event.target !== this) {\n", + " // Ignore bubbled events from children.\n", + " return;\n", + " }\n", + " fig.close_ws(fig, {});\n", + "};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (el) {\n", + " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (el) {\n", + " // this is important to make the div 'focusable\n", + " el.setAttribute('tabindex', 0);\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " } else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager) {\n", + " manager = IPython.keyboard_manager;\n", + " }\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which === 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " fig.ondownload(fig, null);\n", + "};\n", + "\n", + "mpl.find_output_cell = function (html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i = 0; i < ncells; i++) {\n", + " var cell = cells[i];\n", + " if (cell.cell_type === 'code') {\n", + " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", + " var data = cell.output_area.outputs[j];\n", + " if (data.data) {\n", + " // IPython >= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] === html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "};\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel !== null) {\n", + " IPython.notebook.kernel.comm_manager.register_target(\n", + " 'matplotlib',\n", + " mpl.mpl_figure_comm\n", + " );\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "# Setup to analyse an MDP Playground experiment\n", "from mdp_playground.analysis import MDPP_Analysis\n", @@ -190,39 +4369,23 @@ "#The converted mdpp csvs will be stored in output_dir\n", "output_dir = \"../mdpp_to_cave\"\n", "mdpp_cave = MDPPToCave(output_dir)\n", - "cave_input_file = mdpp_cave.to_bohb_results(dir_name, exp_name)\n", - "\n", - "cave_input_file = \"../mdpp_to_cave/%s\"%exp_name\n", - "\n", - "# Similarly, as an example, cave will ouput it's results \n", - "# to the same directory as cave's input files\n", - "\n", - "cave_results = os.path.join(cave_input_file, \"out\")\n", - "cave = CAVE(folders = [cave_input_file],\n", - " output_dir = cave_results,\n", - " ta_exec_dir = [cave_input_file],\n", - " file_format = \"BOHB\",\n", - " show_jupyter=True,\n", - " )\n", - "cave.performance_table()\n", - "cave.local_parameter_importance()\n", - "cave.cave_fanova()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "scrolled": false - }, - "outputs": [], - "source": [ - "weights = {}\n", - "weights['reward_noise'] = [.2, .2, .2, .2, .2, .0, .0, .0]\n", - "weights['action_loss_weight'] = [.33, .33, .33, .0, .0, .0]\n", + "for exp_name, v in experiments.items():\n", + " dir_name, _ = os.path.split(v)\n", + " cave_input_file = mdpp_cave.to_bohb_results(dir_name, exp_name)\n", + " print(cave_input_file)\n", + " # Similarly, as an example, cave will ouput it's results \n", + " # to the same directory as cave's input files\n", "\n", - "# Plot radar(spider) plot: Training: across different meta-features\n", - "mdpp_analysis.plot_radar(list_exp_data, save_fig, weights=weights)" + " cave_results = os.path.join(cave_input_file, \"out\")\n", + " cave = CAVE(folders = [cave_input_file],\n", + " output_dir = cave_results,\n", + " ta_exec_dir = [cave_input_file],\n", + " file_format = \"BOHB\",\n", + " show_jupyter=True,\n", + " )\n", + " cave.performance_table()\n", + " cave.local_parameter_importance()\n", + "# cave.cave_fanova()" ] }, { @@ -230,10 +4393,7 @@ "execution_count": null, "metadata": {}, "outputs": [], - "source": [ - "# Plot radar(spider) plot: Evaluation: across different meta-features\n", - "mdpp_analysis.plot_radar(list_exp_data, save_fig, train=False)" - ] + "source": [] } ], "metadata": { diff --git a/run_experiments_baselines.py b/run_experiments_baselines.py index 1fcdedf..57755e9 100644 --- a/run_experiments_baselines.py +++ b/run_experiments_baselines.py @@ -38,6 +38,28 @@ import itertools import pprint + +def create_gym_env_wrapper_atari(config): + from gym.envs.atari import AtariEnv + from mdp_playground.envs.gym_env_wrapper import GymEnvWrapper + ae = AtariEnv(**config["AtariEnv"]) + gew = GymEnvWrapper(ae, **config) ##IMP Had initially thought to put this config in config["GymEnvWrapper"] but because of code below which converts var_env_configs to env_config, it's best to leave those configs as top level configs in the dict! + return gew + +def create_gym_env_wrapper_frame_stack_atari(config): #hack ###TODO remove? + '''When using frameStack GymEnvWrapper should wrap AtariEnv using wrap_deepmind_ray and therefore this function sets "wrap_deepmind_ray": True and 'frame_skip': 1 inside config so as to keep config same as for create_gym_env_wrapper_atari above and reduce manual errors when switching between the 2. + ''' + config["wrap_deepmind_ray"] = True #hack + config["frame_skip"] = 1 #hack + from gym.envs.atari import AtariEnv + from mdp_playground.envs.gym_env_wrapper import GymEnvWrapper + import gym + game = config["AtariEnv"]["game"] + game = ''.join([g.capitalize() for g in game.split('_')]) + ae = gym.make('{}NoFrameskip-v4'.format(game)) + gew = GymEnvWrapper(ae, **config) ##IMP Had initially thought to put this config in config["GymEnvWrapper"] but because of code below which converts var_env_configs to env_config, it's best to leave those configs as top level configs in the dict! + return gew + class CustomCallback(sb.common.callbacks.BaseCallback): """ Callback for evaluating an agent. @@ -75,6 +97,7 @@ def __init__( # Convert to VecEnv for consistency if not isinstance(eval_env, VecEnv): eval_env = DummyVecEnv([lambda: eval_env]) + eval_env = VecNormalize(eval_env, norm_obs=False, norm_reward=True, clip_obs=10.) if isinstance(eval_env, VecEnv): assert eval_env.num_envs == 1, "You must pass only one environment for evaluation" @@ -132,8 +155,9 @@ def write_train_result(self): env = env.unwrapped.envs[0]#only using one environment #A2C can handle multiple envs.. - if(self.config_algorithm == "A2C" or self.config_algorithm =="A3C"): - env = env.envs[0]#take first env + # if(self.config_algorithm == "A2C" or self.config_algorithm =="A3C"): + # env = env.envs[0]#take first env + # Writes every iteration, would slow things down. #hack fout = open(self.file_name + '.csv', 'a') #hardcoded fout.write(str(training_iteration) + ' ' + config_algorithm + ' ') @@ -240,6 +264,51 @@ def cartesian_prod(args, config): return cartesian_product_configs +def default_timesteps_total(env_config, algorithm): + #default settings for #timesteps_total + if env_config["env"] in ["HalfCheetahWrapper-v3"]: #hack + timesteps_total = 3000000 + + # from mdp_playground.envs.mujoco_env_wrapper import get_mujoco_wrapper #hack + # from gym.envs.mujoco.half_cheetah_v3 import HalfCheetahEnv + # wrapped_mujoco_env = get_mujoco_wrapper(HalfCheetahEnv) + # register_env("HalfCheetahWrapper-v3", lambda config: create_gym_env_wrapper_mujoco_wrapper(config, wrapped_mujoco_env)) + + elif env_config["env"] in ["HopperWrapper-v3"]: #hack + timesteps_total = 1000000 + # from mdp_playground.envs.mujoco_env_wrapper import get_mujoco_wrapper #hack + # from gym.envs.mujoco.hopper_v3 import HopperEnv + # wrapped_mujoco_env = get_mujoco_wrapper(HopperEnv) + # register_env("HopperWrapper-v3", lambda config: create_gym_env_wrapper_mujoco_wrapper(config, wrapped_mujoco_env)) + + elif env_config["env"] in ["PusherWrapper-v2"]: #hack + timesteps_total = 500000 + + # from mdp_playground.envs.mujoco_env_wrapper import get_mujoco_wrapper #hack + # from gym.envs.mujoco.pusher import PusherEnv + # wrapped_mujoco_env = get_mujoco_wrapper(PusherEnv) + # register_env("PusherWrapper-v2", lambda config: create_gym_env_wrapper_mujoco_wrapper(config, wrapped_mujoco_env)) + + elif env_config["env"] in ["ReacherWrapper-v2"]: #hack + timesteps_total = 500000 + + # from mdp_playground.envs.mujoco_env_wrapper import get_mujoco_wrapper #hack + # from gym.envs.mujoco.reacher import ReacherEnv + # wrapped_mujoco_env = get_mujoco_wrapper(ReacherEnv) + # register_env("ReacherWrapper-v2", lambda config: create_gym_env_wrapper_mujoco_wrapper(config, wrapped_mujoco_env)) + + elif env_config["env"] in ["GymEnvWrapper-Atari"]: + if "AtariEnv" in env_config["env_config"]: + timesteps_total = 10_000_000 + else: + if algorithm == 'DQN': + timesteps_total = 20000 + elif algorithm == 'A3C' or algorithm == "A2C": + timesteps_total = 150000 + else: #if algorithm == 'DDPG': + timesteps_total = 20000 + return timesteps_total + def process_dictionaries(config, current_config, var_env_configs, var_agent_configs, var_model_configs): algorithm = config.algorithm agent_config = config.agent_config @@ -581,8 +650,7 @@ def model_to_policy_kwargs(env, config): return policy_kwargs, use_lstm def main(args): - #------------------------- init configuration ----------------------------# - #print("Config file", os.path.abspath(args.config_file)) # 'experiments/dqn_seq_del.py' + # print("Config file", os.path.abspath(args.config_file)) # 'experiments/dqn_seq_del.py' if args.config_file[-3:] == '.py': args.config_file = args.config_file[:-3] @@ -633,7 +701,12 @@ def main(args): #---------- Compute cartesian product of configs ----------------# start = time.time() - cartesian_product_configs = cartesian_prod(args, config) + # cartesian_product_configs = cartesian_prod(args, config) + if args.config_num is None: + cartesian_product_configs = config.cartesian_product_configs + else: + cartesian_product_configs = [config.cartesian_product_configs[args.config_num]] + #------------ Run every configuration ------------------ # pp = pprint.PrettyPrinter(indent=4) @@ -653,7 +726,7 @@ def main(args): # Automatically normalize the input features and reward if (config.algorithm == "DDPG" or config.algorithm == "A2C" or config.algorithm == "A3C"): env = DummyVecEnv([lambda: env]) - env = VecNormalize(env, norm_obs=False, norm_reward=True, clip_obs=10.) + env = VecNormalize(env, norm_obs=False, norm_reward=True, clip_obs=10.) #limit max timesteps in evaluation eval_horizon = 100 @@ -669,7 +742,7 @@ def main(args): agent_config_baselines = copy.deepcopy(agent_config) agent_config_baselines.pop('timesteps_per_iteration') #this is not part of baselines parameters, need to separate else: - timesteps_per_iteration = 1000#default + timesteps_per_iteration = 1000 # default #Set model parameters policy_kwargs, use_lstm = model_to_policy_kwargs(env, config) #return policy_kwargs @@ -678,9 +751,10 @@ def main(args): #Use feed forward policies and specify cnn feature extractor in configuration if config.algorithm == 'DQN': model = DQN(env = env, policy = sb.deepq.policies.FeedForwardPolicy, **agent_config_baselines, verbose=1) - elif config.algorithm == 'DDPG': #hack - #action noise is none by default meaning it does not explore.. - #condiguration using ray defaults https://docs.ray.io/en/latest/rllib-algorithms.html?highlight=ddpg#deep-deterministic-policy-gradients-ddpg-td3 + elif config.algorithm == 'DDPG': + # action noise is none by default meaning it does not explore.. + # condiguration using ray defaults + # https://docs.ray.io/en/latest/rllib-algorithms.html?highlight=ddpg#deep-deterministic-policy-gradients-ddpg-td3 n_actions = env.action_space.shape[0] agent_config_baselines["action_noise"] = OrnsteinUhlenbeckActionNoise( mean=np.zeros(n_actions),\ @@ -697,10 +771,10 @@ def main(args): model = SAC(env = env, policy = sb.sac.policies.FeedForwardPolicy ,**agent_config_baselines, verbose=1) #------------ train/evaluation ------------------ # - if env_config["env"] in ["HopperWrapper-v3", "HalfCheetahWrapper-v3"]: - timesteps_total = 500000 + if 'timesteps_total' in dir(config): + timesteps_total = config.timesteps_total else: - timesteps_total = 20000 #DQN, DDPG, TD3, SAC + timesteps_total = default_timesteps_total(env_config, config.algorithm) # train your model for n_iter timesteps #Define evaluation diff --git a/run_experiments_ray.py b/run_experiments_ray.py index 663180d..30821a3 100644 --- a/run_experiments_ray.py +++ b/run_experiments_ray.py @@ -7,17 +7,48 @@ import numpy as np import copy +import warnings +import logging import ray from ray import tune -#from ray.rllib.utils.seed import seed as rllib_seed +from ray.rllib.utils.seed import seed as rllib_seed import mdp_playground from mdp_playground.envs import RLToyEnv from ray.tune.registry import register_env -register_env("RLToy-v0", lambda config: RLToyEnv(**config)) import sys, os import argparse +register_env("RLToy-v0", lambda config: RLToyEnv(**config)) +register_env("GymEnvWrapper-Atari", lambda config: create_gym_env_wrapper_atari(config)) +register_env("GymEnvWrapperFrameStack-Atari", lambda config: create_gym_env_wrapper_frame_stack_atari(config)) +register_env("RLToy-v0", lambda config: RLToyEnv(**config)) + +def create_gym_env_wrapper_atari(config): + from gym.envs.atari import AtariEnv + from mdp_playground.envs.gym_env_wrapper import GymEnvWrapper + ae = AtariEnv(**config["AtariEnv"]) + gew = GymEnvWrapper(ae, **config) ##IMP Had initially thought to put this config in config["GymEnvWrapper"] but because of code below which converts var_env_configs to env_config, it's best to leave those configs as top level configs in the dict! + return gew + + + +def create_gym_env_wrapper_frame_stack_atari(config): #hack ###TODO remove? + '''When using frameStack GymEnvWrapper should wrap AtariEnv using wrap_deepmind_ray and therefore this function sets "wrap_deepmind_ray": True and 'frame_skip': 1 inside config so as to keep config same as for create_gym_env_wrapper_atari above and reduce manual errors when switching between the 2. + ''' + config["wrap_deepmind_ray"] = True #hack + config["frame_skip"] = 1 #hack + from gym.envs.atari import AtariEnv + from mdp_playground.envs.gym_env_wrapper import GymEnvWrapper + import gym + game = config["AtariEnv"]["game"] + game = ''.join([g.capitalize() for g in game.split('_')]) + ae = gym.make('{}NoFrameskip-v4'.format(game)) + gew = GymEnvWrapper(ae, **config) ##IMP Had initially thought to put this config in config["GymEnvWrapper"] but because of code below which converts var_env_configs to env_config, it's best to leave those configs as top level configs in the dict! + return gew + + + def parse_args(): parser = argparse.ArgumentParser(description=__doc__) # docstring at beginning of the file is stored in __doc__ parser.add_argument('-c', '--config-file', dest='config_file', action='store', default='default_config', @@ -40,37 +71,11 @@ def parse_args(): # ' A Cartesian product of different configuration values for the experiment will be taken and ordered as a list and this number corresponds to the configuration number in this list.' # ' Please look in to the code for details.') - args = parser.parse_args() print("Parsed args:", args) return args def main(args): - def create_gym_env_wrapper_atari(config): - from gym.envs.atari import AtariEnv - from mdp_playground.envs.gym_env_wrapper import GymEnvWrapper - ae = AtariEnv(**config["AtariEnv"]) - gew = GymEnvWrapper(ae, **config) ##IMP Had initially thought to put this config in config["GymEnvWrapper"] but because of code below which converts var_env_configs to env_config, it's best to leave those configs as top level configs in the dict! - return gew - - register_env("GymEnvWrapper-Atari", lambda config: create_gym_env_wrapper_atari(config)) - - - def create_gym_env_wrapper_frame_stack_atari(config): #hack ###TODO remove? - '''When using frameStack GymEnvWrapper should wrap AtariEnv using wrap_deepmind_ray and therefore this function sets "wrap_deepmind_ray": True and 'frame_skip': 1 inside config so as to keep config same as for create_gym_env_wrapper_atari above and reduce manual errors when switching between the 2. - ''' - config["wrap_deepmind_ray"] = True #hack - config["frame_skip"] = 1 #hack - from gym.envs.atari import AtariEnv - from mdp_playground.envs.gym_env_wrapper import GymEnvWrapper - import gym - game = config["AtariEnv"]["game"] - game = ''.join([g.capitalize() for g in game.split('_')]) - ae = gym.make('{}NoFrameskip-v4'.format(game)) - gew = GymEnvWrapper(ae, **config) ##IMP Had initially thought to put this config in config["GymEnvWrapper"] but because of code below which converts var_env_configs to env_config, it's best to leave those configs as top level configs in the dict! - return gew - - register_env("GymEnvWrapperFrameStack-Atari", lambda config: create_gym_env_wrapper_frame_stack_atari(config)) if args.config_file[-3:] == '.py': args.config_file = args.config_file[:-3] @@ -313,7 +318,6 @@ def on_episode_step(info): from functools import reduce def deepmerge(a, b, path=None): '''Merges dict b into dict a - Based on: https://stackoverflow.com/questions/7204805/how-to-merge-dictionaries-of-dictionaries/7205107#7205107 ''' if path is None: path = [] @@ -554,6 +558,9 @@ def create_gym_env_wrapper_mujoco_wrapper(config, wrapped_mujoco_env): #return_trials=True # add trials = tune.run( above ) + end = time.time() + print("No. of seconds to run:", end - start) + if __name__ == '__main__': args = parse_args() main(args) \ No newline at end of file diff --git a/setup.py b/setup.py index 1df594b..4f4495a 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,9 @@ from setuptools import setup +hpo_analysis_require = [ + 'cave==1.4.0', +] + extras_require = [ 'ray[rllib,debug]==0.7.3', 'tensorflow==1.13.0rc1', diff --git a/test_cave_analysis.py b/test_cave_analysis.py new file mode 100644 index 0000000..9452bbe --- /dev/null +++ b/test_cave_analysis.py @@ -0,0 +1,32 @@ +from cave.cavefacade import CAVE +from mdp_playground.analysis.mdpp_to_cave import MDPPToCave +import os + +files_dir = "/mnt/484A4CAB4A4C9798/GoogleDrive/Maestria-Drive/HiWi/mdp_files" +experiments = { +# "a3c_seq" : "%s/a3c_seq/"%files_dir, +# "a3c_lstm_seq" : "%s/a3c_lstm_seq/"%files_dir, +# "a3c_del" : "%s/a3c_del/"%files_dir, + "a3c_lstm_del" : "%s/a3c_lstm_del/"%files_dir, +} + +#The converted mdpp csvs will be stored in output_dir +output_dir = "../mdpp_to_cave" +mdpp_cave = MDPPToCave(output_dir) +for exp_name, v in experiments.items(): + dir_name, _ = os.path.split(v) + cave_input_file = mdpp_cave.to_bohb_results(dir_name, exp_name) + print(cave_input_file) +# Similarly, as an example, cave will ouput it's results +# to the same directory as cave's input files + +cave_results = os.path.join(cave_input_file, "out") +cave = CAVE(folders = [cave_input_file], + output_dir = cave_results, + ta_exec_dir = [cave_input_file], + file_format = "BOHB", + show_jupyter=True, + ) +cave.performance_table() +cave.local_parameter_importance() +# cave.cave_fanova() \ No newline at end of file From f4a4df3562ead3581039a4aaf1000ff74733a74a Mon Sep 17 00:00:00 2001 From: JessicaBorja Date: Sat, 8 May 2021 21:43:13 +0200 Subject: [PATCH 06/22] inspect baselines weights, save best eval model, experiments --- experiments/a3c_del.py | 3 +- experiments/a3c_lstm_del.py | 1 + experiments/a3c_lstm_seq.py | 3 +- experiments/a3c_seq.py | 1 + inspect_weights.py | 69 + mdp_playground/analysis/mdpp_to_cave.py | 29 +- plot_experiments.ipynb | 4418 ++--------------------- rudder_analysis.ipynb | 715 ++++ run_experiments_baselines.py | 74 +- test_cave_analysis.py | 11 +- 10 files changed, 1101 insertions(+), 4223 deletions(-) create mode 100644 inspect_weights.py create mode 100644 rudder_analysis.ipynb diff --git a/experiments/a3c_del.py b/experiments/a3c_del.py index a42e0dc..65bd557 100644 --- a/experiments/a3c_del.py +++ b/experiments/a3c_del.py @@ -1,4 +1,5 @@ num_seeds = 10 +timesteps_total = 1000000 from collections import OrderedDict var_env_configs = OrderedDict({ 'state_space_size': [8],#, 10, 12, 14] # [2**i for i in range(1,6)] @@ -7,7 +8,7 @@ 'sequence_length': [1], 'reward_density': [0.25], # np.linspace(0.0, 1.0, num=5) 'make_denser': [False], - 'terminal_state_density': [0.25], # np.linspace(0.1, 1.0, num=5) + 'terminal_state_density': [0], # np.linspace(0.1, 1.0, num=5) 'transition_noise': [0],#, 0.01, 0.02, 0.10, 0.25] 'reward_noise': [0],#, 1, 5, 10, 25] # Std dev. of normal dist. 'dummy_seed': [i for i in range(num_seeds)], diff --git a/experiments/a3c_lstm_del.py b/experiments/a3c_lstm_del.py index 0fa84ef..c63c532 100644 --- a/experiments/a3c_lstm_del.py +++ b/experiments/a3c_lstm_del.py @@ -1,4 +1,5 @@ num_seeds = 10 +timesteps_total = 1000000 from collections import OrderedDict var_env_configs = OrderedDict({ 'state_space_size': [8],#, 10, 12, 14] # [2**i for i in range(1,6)] diff --git a/experiments/a3c_lstm_seq.py b/experiments/a3c_lstm_seq.py index bf988ac..6e90b08 100644 --- a/experiments/a3c_lstm_seq.py +++ b/experiments/a3c_lstm_seq.py @@ -1,4 +1,5 @@ num_seeds = 10 +timesteps_total = 1000000 from collections import OrderedDict var_env_configs = OrderedDict({ 'state_space_size': [8],#, 10, 12, 14] # [2**i for i in range(1,6)] @@ -40,7 +41,7 @@ "use_pytorch": False, # GAE(gamma) parameter "gamma": 0.99, - "lambda": 0.95, # + "lambda": 0, # # Max global norm for each gradient calculated by worker "grad_clip": 10.0, # low prio. # Learning rate diff --git a/experiments/a3c_seq.py b/experiments/a3c_seq.py index acdc635..1ab720f 100644 --- a/experiments/a3c_seq.py +++ b/experiments/a3c_seq.py @@ -1,4 +1,5 @@ num_seeds = 10 +timesteps_total = 1000000 from collections import OrderedDict var_env_configs = OrderedDict({ 'state_space_size': [8],#, 10, 12, 14] # [2**i for i in range(1,6)] diff --git a/inspect_weights.py b/inspect_weights.py new file mode 100644 index 0000000..e825ca6 --- /dev/null +++ b/inspect_weights.py @@ -0,0 +1,69 @@ +import tensorflow as tf +import stable_baselines as sb +import matplotlib.pyplot as plt +from stable_baselines.common import BaseRLModel +from stable_baselines import DQN, DDPG, SAC, A2C, TD3 +import numpy as np +import argparse +import zipfile +import os +import sys +import gym + + +def parse_args(): + parser = argparse.ArgumentParser(description=__doc__) # docstring at beginning of the file is stored in __doc__ + parser.add_argument('-n', '--file-name', dest="filename", + help="full path where the stable baselines model is stored as a zip") + parser.add_argument('-s', '--save-dir', dest="save_dir", default="../tmp/", + help="Where to save the images") + args = parser.parse_args() + print("Parsed args:", args) + return args + + +def main(args): + env = gym.make('CartPole-v1') + model = A2C(sb.common.policies.MlpLstmPolicy, env) + # model.load(args.filename) + f_path = os.path.abspath(args.filename) + if(os.path.exists(f_path+".zip")): + _, params = model._load_from_file(f_path) + else: + print("Path does not exist: %s" % f_path) + return + + if(not os.path.exists(args.save_dir)): + os.makedirs(args.save_dir) + + w = tf.summary.FileWriter("../mdp_files/output/", model.graph) + + min_v, max_v = sys.maxsize, -sys.maxsize - 1 + for v in params.values(): + if(np.max(v) > max_v): + max_v = np.max(v) + elif(np.min(v) < min_v): + min_v = np.min(v) + + exp_name = os.path.abspath(args.filename).split(os.path.sep)[-1] + for k, v in params.items(): + if('w' in k): # weights + p_name = k.split('/')[1] + plt.suptitle(p_name + str(v.shape)) + plt.imshow(v, cmap="twilight") + # plt.show() + plt.clim(min_v, max_v) + plt.colorbar() + save_plot = os.path.join( + args.save_dir, + "%s_%s" % (exp_name, p_name)) + plt.savefig(save_plot, bbox_inches='tight', + pad_inches=0.0, dpi=200) + plt.clf() + plt.close() + return + + +if __name__ == '__main__': + args = parse_args() + main(args) diff --git a/mdp_playground/analysis/mdpp_to_cave.py b/mdp_playground/analysis/mdpp_to_cave.py index 957fb86..203a034 100644 --- a/mdp_playground/analysis/mdpp_to_cave.py +++ b/mdp_playground/analysis/mdpp_to_cave.py @@ -5,9 +5,7 @@ class MDPPToCave(): def __init__(self, output_dir = "../mdpp_to_cave/"): - self.output_folder = output_dir - if not os.path.exists(self.output_folder): - os.makedirs(self.output_folder) + return def _create_configspace_json(self, stats_pd, var_configs): configspace = {"hyperparameters":[], @@ -141,7 +139,12 @@ def to_cave_csv(self, args): ## Creates the bohb file from the mdpp output in the output_folder directory ## this file can be fed into cave for analysis - def to_bohb_results(self, dir_name, exp_name): + def to_bohb_results(self, dir_name, exp_name, output_dir="../cave_output/"): + self.output_folder = output_dir + if not os.path.exists(self.output_folder): + print("Writing bohb to cave output to %s"%(os.path.abspath(output_dir))) + os.makedirs(self.output_folder) + #file_path = args.file_path output_folder = os.path.join(self.output_folder, exp_name) if not os.path.exists(output_folder): @@ -238,20 +241,21 @@ def to_bohb_results(self, dir_name, exp_name): json.dump(d, fout) fout.write('\n') return output_folder - + + if __name__ == "__main__": dir_name = '../../../mdp_files/' exp_name = 'dqn_seq_del' from cave.cavefacade import CAVE import os - #The converted mdpp csvs will be stored in output_dir + # The converted mdpp csvs will be stored in output_dir output_dir = "../../../mdpp_to_cave" mdpp_file = os.path.join(dir_name, exp_name) mdpp_cave = MDPPToCave(output_dir) cave_input_file = mdpp_cave.to_bohb_results(dir_name, exp_name) - #cave_input_file = "../../../mdpp_to_cave/dqn_seq_del" + # cave_input_file = "../../../mdpp_to_cave/dqn_seq_del" # Similarly, as an example, cave will ouput it's results # to the same directory as cave's input files @@ -265,5 +269,12 @@ def to_bohb_results(self, dir_name, exp_name): show_jupyter=True, ) - #cave.plot_scatter() - cave.pimp_forward_selection() \ No newline at end of file + # Common analysis + cave.performance_table() + cave.local_parameter_importance() + + # fanova can only be used with more + # more than 1 meta-feature + cave.cave_fanova() + + # Other analysis diff --git a/plot_experiments.ipynb b/plot_experiments.ipynb index aa4432a..16c17ca 100644 --- a/plot_experiments.ipynb +++ b/plot_experiments.ipynb @@ -10,12 +10,12 @@ "from mdp_playground.analysis import MDPP_Analysis\n", "\n", "# Set the following to True to save PDFs of plots that you generate below\n", - "save_fig = False" + "save_fig = True" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 2, "metadata": { "scrolled": true }, @@ -24,33 +24,14 @@ "name": "stdout", "output_type": "stream", "text": [ - "Loading data from a sequential run/already combined runs of experiment configurations.\n", - "Training stats read (rows, columns): (6000, 15)\n", - "train stats shape: (1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 10, 3)\n", - "train_aucs.shape: (1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 10, 3)\n", - "eval stats shape: (1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 10, 3)\n", - "eval_aucs.shape: (1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 10, 3)\n", - "Dimension varied: sequence_length . The values it took: ['1', '2', '3', '4'] . Number of values it took: 4 . Index in loaded data: 4\n", - "Loading data from a sequential run/already combined runs of experiment configurations.\n", - "Training stats read (rows, columns): (6000, 15)\n", - "train stats shape: (1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 10, 3)\n", - "train_aucs.shape: (1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 10, 3)\n", - "eval stats shape: (1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 10, 3)\n", - "eval_aucs.shape: (1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 10, 3)\n", - "Dimension varied: sequence_length . The values it took: ['1', '2', '3', '4'] . Number of values it took: 4 . Index in loaded data: 4\n", - "Loading data from a sequential run/already combined runs of experiment configurations.\n", + "Loading data from a distributed run of experiment configurations. Creating a combined CSV stats file.\n", + "51 files were combined into 1 for file:/mnt/484A4CAB4A4C9798/GoogleDrive/Maestria-Drive/HiWi/mdp_files/baselines/a3c_lstm_del//a3c_lstm_del_n.csv\n", + "50 files were combined into 1 for file:/mnt/484A4CAB4A4C9798/GoogleDrive/Maestria-Drive/HiWi/mdp_files/baselines/a3c_lstm_del//a3c_lstm_del_n_eval.csv\n", "Training stats read (rows, columns): (50000, 15)\n", "train stats shape: (1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 10, 3)\n", "train_aucs.shape: (1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 10, 3)\n", "eval stats shape: (1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 10, 3)\n", "eval_aucs.shape: (1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 10, 3)\n", - "Dimension varied: delay . The values it took: ['0', '1', '2', '4', '8'] . Number of values it took: 5 . Index in loaded data: 3\n", - "Loading data from a sequential run/already combined runs of experiment configurations.\n", - "Training stats read (rows, columns): (47650, 15)\n", - "train stats shape: (1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 10, 3)\n", - "train_aucs.shape: (1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 10, 3)\n", - "eval stats shape: (1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 10, 3)\n", - "eval_aucs.shape: (1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 10, 3)\n", "Dimension varied: delay . The values it took: ['0', '1', '2', '4', '8'] . Number of values it took: 5 . Index in loaded data: 3\n" ] } @@ -65,11 +46,11 @@ "# For each experiment (also works in case of a single experiment):\n", "# Set exp_name to the name that was given to the experiment when running it, i.e., with the -e option\n", "# Set dir_name to the location where the CSV files from running an experiment were saved\n", - "files_dir = \"/mnt/484A4CAB4A4C9798/GoogleDrive/Maestria-Drive/HiWi/mdp_files\"\n", + "files_dir = \"/mnt/484A4CAB4A4C9798/GoogleDrive/Maestria-Drive/HiWi/mdp_files/baselines\"\n", "experiments = {\n", - " \"a3c_seq\" : \"%s/a3c_seq/\"%files_dir,\n", - " \"a3c_lstm_seq\" : \"%s/a3c_lstm_seq/\"%files_dir,\n", - " \"a3c_del\" : \"%s/a3c_del/\"%files_dir,\n", + "# \"a3c_seq\" : \"%s/a3c_seq/\"%files_dir,\n", + "# \"a3c_lstm_seq\" : \"%s/a3c_lstm_seq/\"%files_dir,\n", + "# \"a3c_del\" : \"%s/a3c_del/\"%files_dir,\n", " \"a3c_lstm_del\" : \"%s/a3c_lstm_del/\"%files_dir,\n", "}\n", "\n", @@ -79,9 +60,22 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "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/3j233//h37XbrrppjzxiU98WGmbDN3B+8lPfjLLli3Lk570pCRDv6vXXHNNrrnmmofWrVy5Mttuu+06565atSrPfvazM2PGjFx11VUPjT//+c/PNddck+uuuy4zZsx4aHyPPfbIzJkz11m7Phv7b5kkVXVZa23BRi8GAAAAAABj5I5gAPrq/PPPz+Me97i8+tWvXmf87W9/+8PWnnvuuVmzZk2OPvro3Hbbbet8HXLIIXnwwQdz4YUXbvD9hpfAq1atyu9///usWrUqBx54YJYuXZq77777oflFixblpptuygUXXPDQ2I9//OMsW7YsRx999ER/ZAAAAAAAmHIz+x2AiVjc7wCbbLrczdjPHJt6V/V0+AwH+fNj+rj66quz7777rnPHbZLsvPPO2WGHHdYZW7p0aZLkRS960Xqvt3z58g2+3y233JJ3vetd+cY3vpFbbrnlYfN33nlntttuuyTJK17xihx//PE544wzcsghhyRJzjjjjGy99dYPK64BAAAAAGA6UQQDMDDWPs7g7LPPzs477zzqmrXbQq/v/IMPPjhLly7NG9/4xixYsCDbb799ZsyYkS984Qs555xz8uCDDz60fptttsnhhx+e0047LcuXL88222yTc889Ny9+8Yszb968yf3hAAAAAABgEimC2UIt7neAAbe43wHokCc96UlZtmxZHnjggXXuCr7pppty5513rrP2KU95SpJk7ty5G7wreH1+8Ytf5Oc//3lOPPHEvOc971ln7vOf//yo5yxatCif+tSnctZZZ2X77bfPqlWrbAsNAAAAAMC05xnBAPTVS17ykixfvjxnn332OuMf+MAHHrb20EMPzaxZs3LSSSflnnvuedj8XXfdlTVr1qz3vdYWzW3E3uK//OUvc9555416zt57753nPOc5OfPMM3PGGWdk1113zcEHH7zRnwsAAAAAAPrJHcEA9NXb3va2nHPOOTn22GNz2WWX5elPf3oWL16cSy65JHPnzl1n7S677JLPfOYzOeaYY7LXXnvliCOOyG677ZZbb701V155Zc4///xcddVVmT9//qjvtddee+XpT396PvjBD2bVqlXZc8898+///u857bTT8sxnPjOXXXbZqOctWrQoxxxzTJLkpJNOylZb+XdUAAAAAABMb4pgAPpqxx13zEUXXZQ3v/nND90VvP/+++eHP/xhDjro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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], "source": [ "# 1-D: Plots showing reward after 20k timesteps when varying a single meta-feature\n", "# Plots across 10 runs: Training: with std dev across the runs\n", @@ -90,9 +84,22 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "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Dp/4xCeyxx57jDtm4xHXE80/4ogjsmbNmrz61a/OyMhIFi9enAULFuTjH/94zj333Nx33333j99xxx1z1FFH5Ywzzsi6deuy44475vzzz88f/dEfZenSpf394QAAAAAAoI+EyQAMvUc+8pG58sorc++9926yO/n666/PrbfeusnYxzzmMUmSJUuWbHZ38kR+8IMf5Pvf/35OPvnkvO1tb9uk72Mf+9i4c1asWJEPfehDOeecc7J48eKsX7/eEdcAAAAAAGz1vDMZgKH33Oc+N+vWrcsnPvGJTdrf9a539Yw98sgjs8MOO+Stb31r7rzzzp7+X/7yl9mwYcOE99oYVm/c4bzRD3/4w1xwwQXjzjnggANy8MEH5+yzz85ZZ52VvfbaK0ccccQWfy4AAAAAABgkO5MBGHpveMMbcu655+blL395Vq9encc97nFZuXJlvvWtb2XJkiWbjH34wx+ev//7v8/xxx+f/fffP0cffXT23nvv3Hjjjbn88svzuc99LldccUWWLVs27r3233//PO5xj8u73/3urF+/Pvvuu2/+/d//PWeccUae8IQnZPXq1ePOW7FiRY4//vgkyVvf+tZst52/5wIAAAAAYOsmTAZg6O2222659NJL89rXvvb+3cmHHnpoLr744hx++OE944899tjss88+ec973pMzzjgjt956a5YsWZJ99903p556ah760IdOeK8FCxbkS1/6Ul73utflnHPOyR133JHHP/7xOeecc/L9739/wjD5RS96UV772tfm9ttvz7HHHtufHxwAAAAAAGZRjT2mk80bGRlpq1atGnQZfbF8+fIkycqVKwdaBwyrqkFXsGVf+cqaLFmy/6ysPTIyK8tuszZs2JA99tgjBx10UP7pn/5pSnPXrFmT/fff/L9jVa1urflXAQAAAACgb5yxCQBz4FOf+lR+8YtfZMWKFYMuBQAAAAAAJsUx1wAwi774xS/m6quvzimnnJLHPvax+eM//uNBlwQAAAAAAJMiTAaAWXTCCSfkuuuuy4EHHpiPfexjWbBgwaBLAgAAAACASREmD9jW8M7VQdYwzK/s9s7pmfH8mC/Wrl076BIAAAAAAGBavDMZAAAAAAAAgB52JsM8Zmf84O4NAAAAAACwtRMmM9SEoYO7NwAAAAAAANs2YfK8tnLQBQCz7L77kqQl2Qr+8oJpaf5qBAAA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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], "source": [ "# Plots across 10 runs: Evaluation: with std dev across the runs\n", "mdpp_analysis.plot_1d_dimensions(list_exp_data, save_fig, train=False, plot_type = \"agent\")" @@ -100,9 +107,34 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "AttributeError", + "evalue": "'list' object has no attribute 'replace'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# 1-D: Plots showing reward after 20k timesteps when varying a single meta-feature\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;31m# Plots across 10 runs: Training: with std dev across the runs\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mmdpp_analysis\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplot_1d_dimensions\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlist_exp_data\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msave_fig\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mplot_type\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m\"metric\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m/mnt/484A4CAB4A4C9798/GoogleDrive/Maestria-Drive/HiWi/mdp-playground/mdp_playground/analysis/analysis.py\u001b[0m in \u001b[0;36mplot_1d_dimensions\u001b[0;34m(self, list_exp_data, save_fig, train, metric_num, plot_type)\u001b[0m\n\u001b[1;32m 460\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;34m'_train'\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mtrain\u001b[0m \u001b[0;32melse\u001b[0m \u001b[0;34m'_eval'\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m'_final_reward_'\u001b[0m \u001b[0;34m+\u001b[0m\u001b[0;31m \u001b[0m\u001b[0;31m\\\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 461\u001b[0m \u001b[0mstats_data\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mgroup_key\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0msub_group_key\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'axis_labels'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreplace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m' '\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m'_'\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m\u001b[0;31m \u001b[0m\u001b[0;31m\\\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 462\u001b[0;31m \u001b[0;34m'_'\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstats_data\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mgroup_key\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0msub_group_key\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'metric_names'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mmetric_num\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m'_1d.pdf'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 463\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msavefig\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfig_name\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdpi\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m300\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbbox_inches\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"tight\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 464\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mAttributeError\u001b[0m: 'list' object has no attribute 'replace'" + ] + }, + { + "data": { + "image/png": "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DLoAANgUp59+eg499NAcfvjhOeGEE3LNNdfkoQ996H39CxYsyGWXXZYDDzxwnXkvetGL8pjHPCave93rsmLFivvab7zxxjznOc/J6tWrc8EFF+RJT3rSOvPe/OY357zzzsutt946rZ8LAAAAAAA2hRXBAAytSy+9NJdffnmOPvrovPCFL8ycOXPutyr4wQ9+8P1C4CTZb7/9sv/+++cHP/jBOu3vfOc786tf/SrveMc77hcCr/Wnf/qnOeKII6bscwAAAAAAwFQTBDMrLV68OIsXLx50GUPL98dMcfrpp2e77bbLkiVLMn/+/Dz72c/ORz/60axZs2ajc9esWZNf/vKX2WWXXdZp/+xnP5utttoqRx999HSVDQAAAAAA004QDMBQWr16dc4666wsWbIk2267bZLk6KOPznXXXZfzzjtvo/NPOeWU/PKXv1wn8L399ttz7bXXZt999828efOmrXYAAAAAAJhugmAAhtI555yT3/zmN+sEuc985jOzYMGC+20PPdry5cvz2te+No9+9KPz93//9/e133bbbUmSHXbYYXqKBgAAAACAzWTOoAtgMs4fdAGbrGrQFfQMso7WNm3+TPgOh/n7Y/idfvrpWbBgQRYuXJirr776vvZnPOMZOfvss7Ny5crMnz//fvMuueSSPOtZz8puu+2WL33pS5k7d+59fWsD4Ntvv336PwAAAAAAAEwjQTAAQ+enP/1pli1bltZa9tlnnzHHfPzjH88JJ5ywTtull16aww47LDvuuGOWLVuW3XfffZ3+7bffPnvuuWeuuuqqrFq1yvbQAAAAAAAMLUEws9T5gy5gyJ0/6AKY5T784Q+ntZbTTjstO+200/363/SmN+WMM85YJwi+9NJL8/SnPz3bb799li1blj333HPMZz//+c/Pe97znpx55pk57rjjpukTAAAAAADA9BIEAzBU1qxZk4985CM54IADcuyxx4455oorrsjSpUtz8cUX56CDDspll12Www47LNttt12WLVuWvffee73Pf/3rX5+Pf/zjef3rX58DDjgghxxyyP3GfO1rX8stt9ySI444Yso+FwAAAAAATCVBMABD5Wtf+1p+8Ytf5JhjjlnvmCVLlmTp0qU5/fTTs/POO+ewww7Lrbfemle/+tVZvnx5li9fvs745z3vedl2222TJLvuumv+7d/+LYcffnie9KQn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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], "source": [ "# 1-D: Plots showing reward after 20k timesteps when varying a single meta-feature\n", "# Plots across 10 runs: Training: with std dev across the runs\n", @@ -111,9 +143,34 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "AttributeError", + "evalue": "'list' object has no attribute 'replace'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# Plots across 10 runs: Evaluation: with std dev across the runs\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mmdpp_analysis\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplot_1d_dimensions\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlist_exp_data\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msave_fig\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtrain\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mplot_type\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m\"metric\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m/mnt/484A4CAB4A4C9798/GoogleDrive/Maestria-Drive/HiWi/mdp-playground/mdp_playground/analysis/analysis.py\u001b[0m in \u001b[0;36mplot_1d_dimensions\u001b[0;34m(self, list_exp_data, save_fig, train, metric_num, plot_type)\u001b[0m\n\u001b[1;32m 460\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;34m'_train'\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mtrain\u001b[0m \u001b[0;32melse\u001b[0m \u001b[0;34m'_eval'\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m'_final_reward_'\u001b[0m \u001b[0;34m+\u001b[0m\u001b[0;31m \u001b[0m\u001b[0;31m\\\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 461\u001b[0m \u001b[0mstats_data\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mgroup_key\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0msub_group_key\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'axis_labels'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreplace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m' '\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m'_'\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m\u001b[0;31m \u001b[0m\u001b[0;31m\\\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 462\u001b[0;31m \u001b[0;34m'_'\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstats_data\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mgroup_key\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0msub_group_key\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'metric_names'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mmetric_num\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m'_1d.pdf'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 463\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msavefig\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfig_name\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdpi\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m300\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbbox_inches\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"tight\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 464\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mAttributeError\u001b[0m: 'list' object has no attribute 'replace'" + ] + }, + { + "data": { + "image/png": "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dTrvXb4gyUtba1YlAwAAAAAAAHQNNExurR08wX7Lk9Qk5h23f2vt7yY6BwAAAAAAAMB8NjTvTAYAAAAAAABg9gx6m2sA5qBbb701N9xwQ+6+++5BlzJvLViwIAsXLszixYuzcOHCQZcDAAAAAMA8JEwG4F5uvfXWXH/99dl5552zaNGiVE34LQP0SWst99xzT26//fb84he/yI477phtttlm0GUBAAAAADDPCJMBhtDBBx+cJFm+fHnf577hhhuy8847Z4sttuj73ExMVeU+97lP7ne/+2XzzTfPddddJ0wGAAAAAGDWeWcyAPdy9913Z9GiRYMug65FixblrrvuGnQZAAAAAADMQ8JkAHrY2nru8G8BAAAAAMCgCJMBAAAAAAAA6CFMBgAAAAAAAKCHMBkAAAAAAACAHsJkgCmqGtznvPM6n5mY+6qrkhUrxv8M8juP9+mXW265JYsWLUpV5fTTT++5vnr16px88sk57LDDsttuu2XRokXZY489csQRR+Syyy5b77xvf/vbs//++2fbbbfNZpttll122SVLlizJ2WefndZa/74EAAAAAAD0mTAZgHnv4x//eO66667svvvuOfXUU3uuX3nllTn66KOzcuXKHHXUUfnABz6QI444Il/5yley3377ZdmyZT1jLrjgguyzzz5529vell122SVLly7NiSeemFe84hW59tprs2TJknz4wx+eja8HAAAAAABTsmDQBQDAoJ1yyik55JBDcthhh+XYY4/N5Zdfnj322OP31xcvXpzvfe972W+//e417oUvfGEe9ahH5fWvf31WrFjx+/brrrsuz372s7N69eqcd955Oeigg+417i1veUu+8pWv5JZbbpnR7wUAAAAAANNhZTIA89rFF1+cSy65JEceeWRe8IIXZMGCBT2rk7fbbrueIDlJ9tlnn+y777750Y9+dK/297znPbnhhhvy7ne/uydIXutP//RPc/jhh/ftewAAAAAAQL8JkwGY10455ZRstdVWWbJkSbbffvs861nPymmnnZY1a9ZscOyaNWvyq1/9KjvuuOO92j/96U9ns802y5FHHjlTZQMAAAAAwIwTJgMMpeXdD9OxevXqnHnmmVmyZEm23HLLJMmRRx6Zq6++Ol/5ylc2OP7EE0/Mr371q3uFxrfddluuuuqqPOxhD8uiRYtmrHYAAAAAAJhpwmQA5q2zzz47v/71r+8VBj/jGc/I4sWLe7a6Huv888/P6173ujzykY/Mm970pt+333rrrUmSrbfeemaKBgAAAACAWbJg0AUAwKCccsopWbx4cXbZZZf8/Oc//3370572tJx11lm56aabsv322/eMu+iii/LMZz4zO+20U77whS9k4cKFv7+2NkS+7bbbZv4LAAAAAADADBImAzAvXXHFFVm2bFlaa9lzzz3H7XPGGWfk2GOPvVfbxRdfnEMPPTTbbLNNli1blp133vle1+973/tm1113zU9+8pOsWrXKVtcAAAAAAAwtYTIA89JHP/rRtNZy8sknZ9ttt+25ftxxx+XUU0+9V5h88cUX56lPfWrue9/7ZtmyZdl1113Hnft5z3te3ve+9+X000/P0UcfPUPfAAAAAAAAZpYwGYB5Z82aNfnYxz6Whz/84Xn5y18+bp9LL700S5cuzYUXXpj9998/3/ve93LooYdmq622yrJly7L77ruvc/43vOENOeOMM/KGN7whD3/4w/O4xz2up89Xv/rVrFy5MocffnjfvhcAAAAAAPSTMBmAeeerX/1qfvnLX+aoo45aZ58lS5Zk6dKlOeWUU7LDDjvk0EMPzS233JJXv/rVOf/883P++effq/9zn/vcbLnllkmSBzzgAfn85z+fww47LAcddFD+/M//PE984hOz9dZb59prr82Xv/zlfOtb38qHP/zhGf2eAAAAAAAwHcJkAOadU045JUlnO+p12XfffbPnnnvmk5/8ZA477LDcfPPNSZKlS5eO2/+KK674fZicJAcccEAuvfTSnHDCCTnnnHNy/PHHZ9WqVdlhhx1y4IEH5rOf/Wye85zn9O9LAQAAAABAn1VrbdA1DJWRkZG2YsWKQZfRFwcffHCSZPny5QOtA4ZV1aArmBlf+tJl2X77vTfYb2RkFoohSXLZZZdl773X/29SVRe11vyrAAAAAADQN5sMugAAAAAAAAAA5h5hMgAAAAAAAAA9hMkAAAAAAAAA9Fgw6ALmu7nwztVB1jDMr+z2zunp8fwAAAAAAADmNiuTAQAAAAAAAOhhZTLMY1bGD+7eAAAAAAAAc50wmaEmDB3cvQEAAAAAANi4CZPnteWDLgCYg9asSZKWZA78tQZp/moEAAAAAIABESYDA7J80AWwDjfffJ/ssMOqJFsMuhSSrFq1KptvvvmgywAA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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], "source": [ "# Plots across 10 runs: Evaluation: with std dev across the runs\n", "mdpp_analysis.plot_1d_dimensions(list_exp_data, save_fig, train=False, plot_type = \"metric\")" @@ -121,9 +178,22 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "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93xNkmTvvd+Yo49+S/7jPz62wtjFi6/J0Ue/KXvs8dIceeT/hrZ77/3GHHXUm3PKKR/NXnu9Idts85CVXu+1r/2nHHzwh1Zoe+lL35RXvOIvc9JJR+bZz355kuShD31MHvvYnXLWWSfnDW84MjNnzvzz+JNOOik77LBDnvKUp0z6+wMAAAAAwNpgRTAwAefFilb65bvf/XLue98H5HnP23eF9le96h33GPvtb38py5bdnj33fG1uumnxCq+nP/35ufvuu3PRRd9a5fU23PDef36/dOmtuemmP2Tp0luz447PzG9+c1mWLLn5z/0vetEBWbz4mnz/+1/7c9uPf/y9XHHFFXnta1870a8MAAAAAABrnRXBDIwVrYO7NkwlV1316zzqUTuusOI2SbbYYqvc5z6brdD2m99cliQ56KDdVjrfDTdct8rr3XDD9fmXf/mnfO97X8kNN1x/j/4lS27KxhtvkiTZffe/y0c/+paceeans/POz0+SnHnmp7PBBhtk3333vce5AAAAAAAwVQiCAZhGRn6D4n3v+2zud7+txh0xb97Kt4VureXgg/fIlVdelpe+9M3ZYYf52XjjTTNjxsx89aufyTnnnJK77777z+PnzNkwz3nOPjn99H/NH/5wXWbP3jDf/vaXsueee2bu3Ln9/WoAAAAAANBHguBp67xBFzDNnTfoAoCeefMekoULr8hdd921wqrgxYuvyS233LTC2Ac+8GFJkk033SJPetLKVwWvzBVX/L9cccVPsv/+h+fAA9+3Qt9XvvKpcc950YsOyGmn/XPOOuvkbLzxplm69FbbQgMAAAAAMOV5RjAAA7Xzzi/IDTdcl7PO+uwK7Sef/H/uMXa33V6SDTaYnRNOeE+WLr3tHv1Llvwxy5bdvtJrzZgxEjS3MXuz//KX/5Pzzjtj3HMe9rDH5dGPfmLOPPOkfOUrn86WWz4oe+yxx2q/FwAAAAAADJIVwQAM1L77HpZzzjklH/zg63L55RfnIQ95dC6++LxceukPstlmW6ww9gEP2CbveMe/5AMf2D8veckOec5zXpmttto2N964KL/61aU577wv59RTf5att95u3Gs9+ME75CEPeXQ+97mPZOnSW7Ptto/IwoW/yBln/Gse+tDH5rLLLh73vBe96IAceeT+SZLXve49mTHD71EBAAAAADC1CYIBGKhNNtk8J554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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], "source": [ "# This and the next cell do the same as the previous 2 cells but plot episode mean lengths instead of episode reward\n", "mdpp_analysis.plot_1d_dimensions(list_exp_data, save_fig, metric_num=-1, plot_type = \"agent\")" @@ -131,4227 +201,211 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": { "scrolled": false }, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], "source": [ "mdpp_analysis.plot_1d_dimensions(list_exp_data, save_fig, train=False, metric_num=-1, plot_type = \"agent\")" ] }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# IMPORTANT: The 2-D plots here are for the 1st experiment in the experiments dict above\n", - "# 2-D heatmap plots across runs: Training runs: with std dev across the runs\n", - "# There seems to be a bug with matplotlib - x and y axes tick labels are not correctly set even though we pass them. Please feel free to look into the code and suggest a correction if you find it.\n", - "mdpp_analysis.plot_2d_heatmap(list_exp_data, save_fig)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "scrolled": false - }, - "outputs": [], - "source": [ - "# 2-D heatmap plots across runs: Evaluation runs: with std dev across the runs\n", - "mdpp_analysis.plot_2d_heatmap(list_exp_data, save_fig, train=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Plot learning curves: Training: Each curve corresponds to a different seed for the agent\n", - "mdpp_analysis.plot_learning_curves(list_exp_data, save_fig)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Plot learning curves: Evaluation: Each curve corresponds to a different seed for the agent\n", - "mdpp_analysis.plot_learning_curves(list_exp_data, save_fig, train=False)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "scrolled": false - }, - "outputs": [], - "source": [ - "weights = {}\n", - "weights['reward_noise'] = [.2, .2, .2, .2, .2, .0, .0, .0]\n", - "weights['action_loss_weight'] = [.33, .33, .33, .0, .0, .0]\n", - "\n", - "# Plot radar(spider) plot: Training: across different meta-features\n", - "mdpp_analysis.plot_radar(list_exp_data, save_fig, weights=weights)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Plot radar(spider) plot: Evaluation: across different meta-features\n", - "mdpp_analysis.plot_radar(list_exp_data, save_fig, train=False)" - ] - }, - { - "cell_type": "code", - "execution_count": 10, + "execution_count": 9, "metadata": {}, "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[1;31mLoading data from a sequential run/already combined runs of experiment configurations.\u001b[0;0m\n", - "../mdpp_to_cave/a3c_seq\n" - ] - }, - { - "data": { - "text/html": [ - "\n", - "\n", - "
\n", - "
\n", - "
\n", - " \n", - "
\n", - "
\n", - "
\n", - "
\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
DefaultIncumbent
Quality-49.69-89.84
\n", - "
\n", - "
\n", - "
\n", - " \n", - "
" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, { "name": "stderr", "output_type": "stream", "text": [ - "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/pimp/evaluator/local_parameter_importance.py:268: RuntimeWarning: invalid value encountered in double_scalars\n", - " overall_var_per_tree = {p : [t / sum_var_per_tree[idx] for idx, t in enumerate(trees)] for p, trees in\n", - "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/pimp/evaluator/local_parameter_importance.py:402: UserWarning: Attempted to set non-positive top ylim on a log-scaled axis.\n", - "Invalid limit will be ignored.\n", - " ax1.set_ylim([min_y * 0.95, max_y])\n" + "/mnt/484A4CAB4A4C9798/GoogleDrive/Maestria-Drive/HiWi/mdp-playground/mdp_playground/analysis/analysis.py:546: UserWarning: FixedFormatter should only be used together with FixedLocator\n", + " plt.gca().set_xticklabels(tick_labels[0])\n" ] }, { "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute('style', 'box-sizing: content-box;');\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " var nentries = entries.length;\n", - " for (var i = 0; i < nentries; i++) {\n", - " var entry = entries[i];\n", - " var width, height;\n", - " if (entry.contentBoxSize) {\n", - " if (entry.contentBoxSize instanceof Array) {\n", - " // Chrome 84 implements new version of spec.\n", - " width = entry.contentBoxSize[0].inlineSize;\n", - " height = entry.contentBoxSize[0].blockSize;\n", - " } else {\n", - " // Firefox implements old version of spec.\n", - " width = entry.contentBoxSize.inlineSize;\n", - " height = entry.contentBoxSize.blockSize;\n", - " }\n", - " } else {\n", - " // Chrome <84 implements even older version of spec.\n", - " width = entry.contentRect.width;\n", - " height = entry.contentRect.height;\n", - " }\n", - "\n", - " // Keep the size of the canvas and rubber band canvas in sync with\n", - " // the canvas container.\n", - " if (entry.devicePixelContentBoxSize) {\n", - " // Chrome 84 implements new version of spec.\n", - " canvas.setAttribute(\n", - " 'width',\n", - " entry.devicePixelContentBoxSize[0].inlineSize\n", - " );\n", - " canvas.setAttribute(\n", - " 'height',\n", - " entry.devicePixelContentBoxSize[0].blockSize\n", - " );\n", - " } else {\n", - " canvas.setAttribute('width', width * fig.ratio);\n", - " canvas.setAttribute('height', height * fig.ratio);\n", - " }\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'width: ' + width + 'px; height: ' + height + 'px;'\n", - " );\n", - "\n", - " rubberband_canvas.setAttribute('width', width);\n", - " rubberband_canvas.setAttribute('height', height);\n", - "\n", - " // And update the size in Python. We ignore the initial 0/0 size\n", - " // that occurs as the element is placed into the DOM, which should\n", - " // otherwise not happen due to the minimum size styling.\n", - " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " rubberband_canvas.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " var cursor = msg['cursor'];\n", - " switch (cursor) {\n", - " case 0:\n", - " cursor = 'pointer';\n", - " break;\n", - " case 1:\n", - " cursor = 'default';\n", - " break;\n", - " case 2:\n", - " cursor = 'crosshair';\n", - " break;\n", - " case 3:\n", - " cursor = 'move';\n", - " break;\n", - " }\n", - " fig.rubberband_canvas.style.cursor = cursor;\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " evt.data.type = 'image/png';\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " evt.data\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", - "mpl.findpos = function (e) {\n", - " //this section is from http://www.quirksmode.org/js/events_properties.html\n", - " var targ;\n", - " if (!e) {\n", - " e = window.event;\n", - " }\n", - " if (e.target) {\n", - " targ = e.target;\n", - " } else if (e.srcElement) {\n", - " targ = e.srcElement;\n", - " }\n", - " if (targ.nodeType === 3) {\n", - " // defeat Safari bug\n", - " targ = targ.parentNode;\n", - " }\n", - "\n", - " // pageX,Y are the mouse positions relative to the document\n", - " var boundingRect = targ.getBoundingClientRect();\n", - " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n", - " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n", - "\n", - " return { x: x, y: y };\n", - "};\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * http://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " var canvas_pos = mpl.findpos(event);\n", - "\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " var x = canvas_pos.x * this.ratio;\n", - " var y = canvas_pos.y * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We want\n", - " * to control all of the cursor setting manually through the\n", - " * 'cursor' event from matplotlib */\n", - " event.preventDefault();\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.which === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.which;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.which !== 17) {\n", - " value += 'ctrl+';\n", - " }\n", - " if (event.altKey && event.which !== 18) {\n", - " value += 'alt+';\n", - " }\n", - " if (event.shiftKey && event.which !== 16) {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k';\n", - " value += event.which.toString();\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(msg['content']['data']);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " var manager = IPython.notebook.keyboard_manager;\n", - " if (!manager) {\n", - " manager = IPython.keyboard_manager;\n", - " }\n", - "\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], + "image/png": "iVBORw0KGgoAAAANSUhEUgAABasAAAFCCAYAAAD/g4GlAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAvnElEQVR4nO3de7xtZVk3/N+1VUAgIQVTICXxrHkIMbEnj/W+lq9ZmqWGyoNIB/FA9VSmIqJJqSiJlm01T0kPaIT66FOJBlmIgEriAUQRDyDk9oAi4AGu9485dy4Xc6+95t5rrjH3Wt8vn/EZa97jHve4FvuzxP3b975GdXcAAAAAAGBIG4YuAAAAAAAAhNUAAAAAAAxOWA0AAAAAwOCE1QAAAAAADE5YDQAAAADA4ITVAAAAAAAM7qZDFwAAAAAAsN7dsu7Y3881U91zdb7yz939iBmVtOqE1QAAAAAAA/t+rsn96mlT3XNGH7vXjMoZhDYgAAAAAAAMzs5qAAAAAIB5UFPO75lUMRhhNQAAAADAwCpJbZgyrb5hJqUMRlgNAAAAADC0SmrandVrjLAaAAAAAGAerPO0WlgNAAAAADAH1nlWLawGAAAAABheTd+zeo0RVgMAAAAADK2y7rdWC6sBAAAAAObAOs+q109YfbPatXfJnkOXAczQev8fdABYCzbcdMPQJQAzttft9hi6BGDGPve5T23q7r2HrmNHM9pYvb7DjXUTVu+SPXNgDh+6DGCGbrrzTYYuAQDYTrvtdfOhSwBm7NCX/tLQJQAz9pjH3usLQ9eww1rfWfX6CasBAAAAAOZWxQsWhy4AAAAAAAAtToXVAAAAAADzYJ2n1cJqAAAAAIA5sM6zamE1AAAAAMDgqvSsHroAAAAAAACy7rdWbxi6AAAAAAAAEFYDAAAAAAysMtpYPc2xrHWr7lJVb6uqT1fVVVV1TVVdWFWvqKrbbmH+aVX1jar6TlV9sKoetsLf7kTagAAAAAAAzIGaTRuQ/ZLcNsk/Jvlykh8k+ekkRyR5fFXdp7v/a/z8A5KcNZ7z0iRXJXlakn+uql/q7tNnUeBmwmoAAAAAgHkwg6y6u9+f5P03elTVvyU5JcmhGQXTSXJckj2THNjd54/nvSXJJ5O8pqru2t298lWOaAMCAAAAADC0SmpDTXVspy+Mzz+eJFW1W5JfSXLG5qA6Sbr76iSvT3LnJAdt70OXYmc1AAAAAMA8mEkXkPHSVbsk2T3JLknunuQvxpfeOz7fK8nOST404fazx+eDkpwzqxqF1QAAAAAAc2AbelbvVVXnLfi8sbs3bmHu4UlOXPD50iSHdPcHx5/3GZ8vm3Dv5rF9py1wGsJqAAAAAIDB1baE1Zu6+37LnHtakgsz2l1934xafuy14Pqu4/N3J9x73aI5MyGsBgAAAAAYWmWmbxjs7i8n+fL442lV9Q9Jzq2qXbv7uCTXjK/tPOH2XcbnayZcWzFesAgAAAAAMLDKqA3INMf26O6PJ/lYkt8bD10+Pk9q9bF5bFKLkBVjZzUAAAAAwBzYzvx5W9w8yS3HX1+QUQuQgyfMe8D4fN6EaytmVXZWV9WTq+pjVXVtVV1ZVa+vqr23ca0NVfWhquqq+j8rXSsAAAAAwCCqpjuWtWTdZgvjD01yzyRnJ0l3X53k3UkeUlX3XjBv94xeznhxknO27xtc2sx3VlfVUUlekeTMJM9Ksl+S309ycFXdv7u/M+WSv5fRv0QAAAAAgLVh+fnztP66qm6b5ANJvpBR/+kDkzw+ybeT/MGCuc9J8vAk/1JVr0zyrSRPy6gNyCO7u2dS4dhMw+qq2ivJi5Ocm+Th3X39ePzcJO/KKLx+yRTr7Tee/4Ikx694wQAAAAAAA6kNM0mr/z7Jk5M8KcneSTqj0Ppvkrysu7+4eWJ3f7aqfi7Jnyf5kyQ7Jflokkd09+mzKG6hWe+s/tUkuyY5cXNQnSTd/e6quiTJIZkirE7ymiSXJPnLCKsBAAAAgLVkBluru/uUJKdMMf/TSR694oUsw6zD6oPG5w9NuHZ2kidU1e7jfihLqqpfT/KoJA/s7uu3922XAAAAAADzojLICxbnyqxfsLjP+HzZhGuXZfRrsM+Eaz+iqvZI8qokf9PdZ69ceQAAAAAAc6AqNeWx1ixrZ3VV7Znk2VOs+6ru/npGLUCS5LsT5lw3Pu864dpiL80oWH/OFDWkqo5IckSS7Jw9prkVAAAAAIBVtNw2IHtm9FLD5fq7JF9Pcs34885Jrl00Z5fx+Zosoap+PqM3Tj6pu785RQ3p7o1JNibJj9U+M31TJQAAAADAdpl1H4w5t6ywursvzahlx7QuH5/3TfLZRdf2zejNk5dnaa9O8p9JPlxVd1x0bdfx2De7e9M21AcAAAAAMBfWYmuPacw6qz93fD54wrUHJLloGS9XvH2S+yS5eNGRJA8df33M9hYKAAAAADAkPatn650ZvRjxyKo6qbuvT5KqelSSOyR5/sLJVXW7jHpYf667vz8efnKSnSas/fYkH0ny57nxrm0AAAAAgB1HJaUNyOx091er6vlJXp7k9Kr6+4zaf/xBkguTnLDolrckeXCSn0py6XiNd01ae/wnB1d09ztmUTsAAAAAwKpag7ulpzHrndXp7uOr6mtJjspol/W3kpyS5E+W0QIEAAAAAGDNq6z7rHr2YXWSdPebkrxpGfMeMsWa6/yXDgAAAABYMyqpDes78lyVsBoAAAAAgKXUut9aLawGAAAAAJgD6zyrFlYDAAAAAMwDbUAAAAAAABiWNywKqwEAAAAA5sE6z6qF1QAAAAAAQ6toAyKsBgAAAACYB+s7qxZWAwAAAAAMrpJa531AhNUAAAAAAIMrbUCGLgAAAAAAAC9Y3DB0AQAAAAAAYGc1AAAAAMA8WOdbq4XVAAAAAABDq+hZPXQBAAAAAADrXWXdb6wWVgMAAAAAzIV1nlYLqwEAAAAA5kAJqwEAAAAAGFQltWHoIoa1zr99AAAAAIB5UKM2INMcy1m16s5VdWxVnV1VX62qb1fV+VX13KrabdHcY6qqt3D84Uy+7QXsrAYAAAAAmAMz6gJyWJKnJ3lXkrcl+X6ShyZ5cZLfqKoHdPe1i+45KsmmRWMfmUl1CwirAQAAAACGVkltmEla/Y4kx3X3VQvGXltVFyd5bpKnJnn1ontO6+5LZ1HMUrQBAQAAAACYBzNoA9Ld5y0Kqjc7eXy+5+RS6hZVtaqbnYXVAAAAAAADq8wkq17KfuPzlROufTzJVUmuq6qzquqXtvtpy6ANCAAAAADAHNiGNiB7VdV5Cz5v7O6NW31O1U2SPD/JD5KctODSN5NsTHJWkm8kuUuSZyd5T1Ud1t1vmrbAaQirAQAAAACGtm3bpTd19/224WknJDk4yZ9290WbB7v7hBuXVX+b5BNJXllV7+juq7fhecuiDQgAAAAAwBxYjTYgVfWiJEdmtAv7uK3N7+6vJXltkj2TPHDbnro8dlYDAAAAAMyBbWgDMt36VcckeV6SNyb5nSluvXR83muFS/oRwmoAAAAAgKFVUivw1sQtLj8Kql+Q5M1JDu/unuL2O43Pk17GuGK0AQEAAAAAWMOq6uiMguq3Jjmsu2+YMOemVbXHhPGfTPK7Sb6W0YsXZ8bOagAAAACAeTCDjdVV9fQkL0zyxSSnJ3nioh3cV3b3+5LsnuTzVXVakk8n+UaSuyQ5fHztCd197cpX+EPCagAAAACAgVVm1rP6oPH5dhm1AFnszCTvS3Jtkn9I8rNJfjWjgHpTRgH3S7v7nFkUt5CwGgAAAABgDsyiZ3V3H5rk0GXM+25Gu6gHI6wGAAAAABhaVTKbndU7DGE1AAAAAMAcmMHG6h2KsBoAAAAAYA7Mog3IjkRYDQAAAAAwtIo2IEMXAAAAAACANiAbVuMhVfXkqvpYVV1bVVdW1eurau9l3rtvVT2nqs6sqq9U1Xeq6pNV9bKqutWsawcAAAAAmLVKUhtqqmOtmXlYXVVHJXlzkquSPCvJ3yR5fJIzqmq3ZSzxqCTHJPlakpcleXaSs8bn86vqNiteNAAAAADAaqua7lhjZtoGpKr2SvLiJOcmeXh3Xz8ePzfJuzIKr1+ylWU+mOT23X3FgrHXVdWHk7wuyR+ODwAAAACAHVPVun/B4qx3Vv9qkl2TnLg5qE6S7n53kkuSHLK1Bbr7k4uC6s1OHp/vuQJ1AgAAAAAMqjZMd6w1s/6WDhqfPzTh2tlJ7lpVu2/j2vuNz1du4/0AAAAAAHOjxrurl3usNbMOq/cZny+bcO2yjPqG7zPh2nK8cHx+8zbeDwAAAAAwP/Ss3rqq2jOjFxou16u6++sZtQBJku9OmHPd+LzrhGtbq+cPkjwuycbu/sAS845IckSS7Jw9pn0MAAAAAMDqqLXZ2mMay33B4p5JXjDFun+X5OtJrhl/3jnJtYvm7DI+X5MpVNXhSV6W5D1JjlxqbndvTLIxSX6s9ulpngMAAAAAsFoqWZOtPaaxrLC6uy/N6N/XtC4fn/dN8tlF1/ZN0gvmbFVVHZZR+PwvSR7b3d/fhpoAAAAAAJgzs95Yfu74fPCEaw9IclF3X72chcZB9euTnJ7kV7t7UmsRAAAAAIAd04aa7lhjZh1WvzOj9h9HVtVNNg9W1aOS3CHJ2xZOrqrbVdVdq+pmi8YPTfK6JB9I8ujuvi4AAAAAAGtFVWrKY61Zbs/qbdLdX62q5yd5eZLTq+rvM2r/8QdJLkxywqJb3pLkwUl+KsmlSVJVv5LkDUm+leTkJI9d9AtxdXefNrNvAgAAAABgFazB/HkqMw2rk6S7j6+qryU5KsmrMgqdT0nyJ8tsAfIzGe0A3zPjlyUu8oUkp61IsQAAAAAAQ1mDrT2mMfOwOkm6+01J3rSMeQ+ZMHZMkmNWuCQAAAAAgLmyFlt7TGNVwmoAAAAAAJZQ2oAIqwEAAAAA5oE2IAAAAAAADKmiDYiwGgAAAABgaFUpO6sBAAAAABjc+s6qhdUAAAAAAPNAGxAAAAAAAAanDQgAAAAAAMMqO6s3DF0AAAAAAAAZ9aye5ljOklV3rqpjq+rsqvpqVX27qs6vqudW1W4T5t+lqk6rqm9U1Xeq6oNV9bAV+f62ws5qAAAAAICBVWa2s/qwJE9P8q4kb0vy/SQPTfLiJL9RVQ/o7mszev4BSc5K8oMkL01yVZKnJfnnqvql7j59Yu1VD562qO4+c/GYsBoAAAAAYA7MqAvIO5Ic191XLRh7bVVdnOS5SZ6a5NXj8eOS7JnkwO4+f1RTvSXJJ5O8pqru2t094RkfyLL3ev+3G3X9EFYDAAAAAKxR3X3eFi6dnFFYfc8kGbcE+ZUkZ2wOqsf3X11Vr09ybJKDkpwzYa0/zI3D6jslOSLJC5Jcs2D8Z5I8cVJBwmoAAAAAgDmwyu9X3G98vnJ8vleSnZN8aMLcs8fniWF1d79y8di4z/VvJ/nr7v7agvEnRlgNAAAAADCnqmbVs3rCo+omSZ6fUW/qk8bD+4zPl024ZfPYvlM85mabH7f48Vu6QVgNAAAAADAHtiGr3quqFrb52NjdG5dx3wlJDk7yp9190Xhs1/H5uxPmX7doznL89Ph8mySbFozfJsl3Jt0grAYAAAAAGFgl27KzelN332+q51S9KMmRGQXbxy24tLmv9M4Tbttl0ZytPePgJH88/vi7SZ4+Ht81yZOTfGbSfTd64yIAAAAAAKuvarpj+vXrmCTPS/LGJL+z6PLl4/OkVh+bxya1CFm4/gFV9aYk/57ks0n+IcnvVtVHq+qUJBdmtOP6rZPut7MaAAAAAGAOzLJn9TiofkGSNyc5vLt70ZQLMmoBcvCE2x8wPp834Vqq6q5Jnpvk8RltkD45ozB8l4yC7p9Ncu8knWRjkhMnrSOsBgAAAAAY2jbull7W0lVHZxRUvzXJYd19w+I53X11Vb07yWOq6t7d/Z/je3dPcniSi5Ocs4VHXJBRSP3+JEd399nj8W8leWBV3THJLZN8rru/tqU6hdUAAAAAAHOgsvJpdVU9PckLk3wxyelJnrhoB/eV3f2+8dfPSfLwJP9SVa/MKGx+Wka7ox85YTf2Zv+WUUj9H1V1y6q6f0a7qC/q7m9192eXU6uwGgAAAABgYKMXLM5k6YPG59tl1AJksTOTvC9JuvuzVfVzSf48yZ8k2SnJR5M8ortP39IDuvvhVbXfeGf2Lyf/nbrfUFXvSXJkd39pa4UKqwEAAAAA5sAswuruPjTJoVPM/3SSR0/zjKq6ZUYvVbxtklOSfC/JIUn+NsmvJDm7qg7s7iuWWmfDNA8FAAAAAGA2qmqqY478cUZB9YO6+wkZ7eCujNqK3DejTdMv2NoidlYDAAAAAMyB+cqfp/LoJG/p7g8vvtDdX6mqNyT5ra0tIqwGAAAAABha1Y6cVt8uyceWuP65JLfZ2iLCagAAAACAObDjZtW5Lku3nL5jkk1bW0RYDQAAAAAwsErmrQ/1NL6U5A4TxquqfibJ7yX531tbxAsWAQAAAADmwOZOIMs95sj7M+pbvVAn+WCSDye5IsnztraIndUAAAAAAGyPjUm+WVV7dfemJNcmuSTJ15L8fZJXdve3t7aIsBoAAAAAYA7sqG1AuvvCJMcu+PyhJHeadh1tQAAAAAAAhjZlC5AdKdeuqptV1YO2Ns/OagAAAACAObAD5c9LqqoNSe6X5GHj4+eS3Dxb2TwtrAYAAAAAGFhlx20DkiRVda/8MJx+UJJbZPSSxcuSvCPJB7a2hrAaAAAAAGAO7KhZdVX9V5K9xh83JfnnjMLpD3T3xctdR1gNAAAAADAHduCd1bfMaBf1hUleleT07v7ctIsIqwEAAAAA5sCOm1XnwflhC5ATkuxcVV9M8q/54Q7ry7a2yJINrVdKVW2oqqOq6sKquq6qvlRVx1fVbqtxPwAAAADAXKtKTXnMi+7+j+5+UXc/NMmPJ/nFJG9Lcrckb0jypaq6aGvrrEpYneSVSV6R5FNJnpHk7UmemeTd4zdDzvp+AAAAAIC5NXrB4nTHPOru67r7/UlenuQvkpyS5Pokd9ravTNvA1JV98goYD61ux+7YPzzGfUveXySk2Z1PwAAAADAjmBeA+jlGHfBeFBGrUAenuTeGWXwn0ryVxm1A1nSauxKfkJGRZ2waPx1Sa5JcsiM7wcAAAAAmHs7ahuQqvr3JN9I8p4kj03y0Yxy29t29z27+1nd/c6trbMaL1g8KMkNSc5ZONjd11XV+ePrs7wfAAAAAGDuzVH+PK2D88Nd1H+b0YsVz+/unmaR1dhZvU+STd393QnXLkuyV1XtNMP7AQAAAADmW+24O6uTPC3J3ye5ZZKXJflIkq9W1alV9YyquvtyFlmNndW7JpkUNCfJdQvmfG+l76+qI5IckSQ7Z4/l1AoAAAAAMIy5yp+Xr7v/NqMd1amqu2XUt/phSR6c5NGj4fqv7r7NUuusRlh9TZJbb+HaLgvmrPj93b0xycYk+bHaZ6ot5wAAAAAAq6WSedstvU26+9NJPp3kNUlSVfdN8tCMXrq4pNUIqy9Pcveq2nlCK499M2rxsaVd1StxPwAAAADA3FsLYfVi3f2xJB9L8oqtzV2NntXnjp9z/4WDVbVLkvskOW/G9wMAAAAAzL2q6Y55UlUbquoeVXWvbV1jNcLqk5N0kmcvGn9aRr2m37Z5oKoOqKq7buv9AAAAAACsrqr6yST/meSCJOdX1flVtff42s2r6iVVddDW1pl5G5DuvqCqXpPkyKo6Ncl7k9wtyTOTnJnkpAXT35/k9lnQSnzK+wEAAAAAdjxVO3IbkJcnOSDJsUluSPKcJH+W5IjuvraqHpLktkn+51KLrEbP6mS0K/rSJEckeWSSTUlOTHJ0d9+wCvcDAAAAAMyt0QsWh65imz0kyWu6+5hktJs6o2D6iPH105P85tYWWY02IOnu67v7+O6+S3fv3N37dvfvd/fVi+bt3903+iVZ7v0AAAAAADuqGu+uXu6xzDWfU1Vvr6pLqqqr6tIl5r5pPGfS8etLPGa3JBct+PyRJLceh9ZJ8oUk+22t1tXaWQ0AAAAAwBJm1AbkJUm+nuSjSfZc5j1PmjB2zhLzP5HkLgs+XzU+3zzJtUluleT6rT1UWA0AAAAAMLSaWRuQA7r7kiSpqk8k2X1rN3T33035jOOSvKWq3tzdn8gPg+kNVbVLkqck+fjWFhFWAwAAAADMgVnsrN4cVE9ZRyX5sSRXL/OdgffJqA3IeVV1WpIfjMePTfKwJHdO8pitLSKsBgAAAAAYWCWpDXPzhsWrMgqrv1dV/5bked394SXmH73g68eNz53kt5N8OskTu/u0rT1UWA0AAAAAMAdm1AZkGlckeWVGL0j8TpJ7J3l2kg9W1S939+lbuO+nJozdkOSb3X31ch8urAYAAAAAGFrVtrQB2auqzlvweWN3b9zWErr7TxYNnVZVJyU5P8lfJ7nTFu774rY+cyFhNQAAAADAHNiGndWbuvt+Myjlv3X3xVV1SpJDq+rO3f2ZWT1LWA0AAAAAMAdm8YLFFXLp+LxXkhuF1VX1xmWsUd196FIThNUAAAAAAAOrzHVYvbn9x5VbuP6kjL6FSSqjly1WkkOXesiGbakMAAAAAICVVTXdsbLPrt2qapcJ4/dN8rgkn+7uz026t7tv2t03WXgk2S3JfZK8NcnHk9x6azXYWQ0AAAAAMLTR1uqVX7bqSUluP/64d5Kdqup5489f6O63jr++U5L/W1WnJbk4yXeS3DvJYUmuT3LENM/t7uuSXJDkKVX13iQvHa+1RcJqAAAAAIA5MKM2IE9N8uBFYy8an8/MaOdzklyR5PQkD03yW0lunuQrSU5Oclx3X7gdNfyfJEdvbZKwGgAAAABgDswiq+7uhyxz3hUZ9Z6ehd2S7FVVu4x3XE+kZzUAAAAAACuiqjZU1U+Mj83x+xuS3CHJ95e6V1gNAAAAADC4Sm2Y7pgnVXWHqjopyTczah/ylSRXjcdu0d1f7O7rl1pDGxAAAAAAgIFVzaYNyGqoqnsk+fckt0hyXpLN/a3vmuQ3kzyiqn6+uz+51DrCagAAAACAOTCjFyyuhuOT3CzJw7r7zIUXqupBSd4znvOIpRbRBgQAAAAAYA5U1VTHHPm5JCcuDqqTpLv/LcmJSf7H1haxsxoAAAAAYA7MV/48le8m+fIS1788nrMkO6sBAAAAAObADryz+r1JHrXE9UeN5yxJWA0AAAAAMLDRCxZ32LD695PsVVX/WFUHV9UtxscDqurUJLcez1mSNiAAAAAAAHNgvvLnqVyZpJLcN8mjF13rzXMWB+zd/SObqYXVAAAAAACDm7vd0tN4U0Zh9XYRVgMAAAAAzIEdNazu7qeuxDrCagAAAACAObCDZtUrRlgNAAAAADCwqqQ2rO+0WlgNAAAAADAH7KwGAAAAAGBwtf3vKNyhCasBAAAAAObB+s6qhdUAAAAAAPOg1nkfkA1DFwAAAAAAAHZWAwAAAAAMrbxgUVgNAAAAADCwSq37NiDCagAAAACAObDOs2phNQAAAADAPLCzGgAAAACAwa3zrDobZv2AqtpQVUdV1YVVdV1Vfamqjq+q3ZZx752r6tiqOruqvlpV366q86vqucu5HwAAAABgh1CjndXTHGvNzMPqJK9M8ookn0ryjCRvT/LMJO+uqq09/7AkRyX5XJJjk/yvJBcleXGSs6rq5rMqGgAAAABgtVRGO6unOdaambYBqap7ZBRQn9rdj10w/vkkr0ry+CQnLbHEO5Ic191XLRh7bVVdnOS5SZ6a5NUrXjgAAAAAwCpbiwH0NGa9s/oJGf2hwAmLxl+X5Jokhyx1c3eftyio3uzk8fme21sgAAAAAMA8qCn/WWtmHVYflOSGJOcsHOzu65KcP76+LfYbn6/c5soAAAAAAObILNqAVNVzqurtVXVJVXVVXbqV+T9bVaeP3x/4rar6p6q6z/Z/d1s30zYgSfZJsqm7vzvh2mVJHlhVO3X395a7YFXdJMnzk/wgS7cQAQAAAADYYczopYkvSfL1JB9NsudWnv+AJGdklN0ePR4+MskHq+qB3X3BLArcbNZh9a5JJgXVSXLdgjnLDqszailycJI/7e6LlppYVUckOSJJds4eUzwCAAAAAGD1zPCliQd09yWjZ9Qnkuy+xNxXZZTVPqi7Lxvfc0qSTyc5Psn/M5MKx2bdBuSaJDtv4douC+YsS1W9KKMkf2N3H7e1+d29sbvv1933u1l2Xe5jAAAAAABWWaVqumM5NgfVW3161R0zatv89s1B9fj+y5K8PckvVNVttuEbW7ZZh9WXJ9mrqiYF1vtm1CJkWbuqq+qYJM9L8sYkv7NiFQIAAAAAzIFZ9Kyewub3C35owrWzk1SSA1f8qQvMOqw+d/yM+y8crKpdktwnyXnLWWQcVL8gyZuTHN7dvaJVAgAAAAAMbBY7q6ewz/h82YRrm8f2XemHLjTrsPrkJJ3k2YvGn5ZRr+q3bR6oqgOq6q6LF6iqozMKqt+a5LDuvmFm1QIAAAAADKWmPEZdLc5bcByxHU/f3Ed50jsIr1s0ZyZm+oLF7r6gql6T5MiqOjXJe5PcLckzk5yZ5KQF09+f5PbZ/K85SVU9PckLk3wxyelJnrjoTwyu7O73zfJ7AAAAAACYU5u6+34rtNbmdwtOauk89fsHt8VMw+qxZye5NMkRSR6ZZFOSE5McvYxd0pv7pNwuoxYgi52ZRFgNAAAAAOzYKrNo7TGNy8fnSa0+No9NahGyYmYeVnf39UmOHx9Lzdt/wtihSQ6dRV0AAAAAAPOiMpOXJk7j3PH54CSvX3TtARm1e/7ILAuYdc9qAAAAAACWYcgXLHb3Z5Ocl+RxVbX5ZYsZf/24JB/o7itW9KGLrEYbEAAAAAAAtmIWG6ur6kkZvSswSfZOslNVPW/8+Qvd/dYF05+V5F+TfLCqThyPPSOjTc9/MIPyfoSwGgAAAABgDsyoZ/VTkzx40diLxuczk/x3WN3dZ1XVQ5K8eHx0krOSPK67/3MWxS0krAYAAAAAmAOzyKq7+yFTzv9QkoevfCVbJ6wGAAAAABjYLPpQ72iE1QAAAAAAc2CdZ9XCagAAAACAeSCsBgAAAABgcNqAAAAAAAAwuHWeVQurAQAAAACGVmVn9YahCwAAAAAAADurAQAAAADmwHrfWS2sBgAAAACYA+s8q9YGBAAAAACA4QmrAQAAAAAYnDYgAAAAAABzYL23ARFWAwAAAADMgcr6TquF1QAAAAAA82B9Z9XCagAAAACAoVVpAyKsBgAAAAAYXGkDMnQBAAAAAABEG5ChCwAAAAAAYN1n1cJqAAAAAIB5UOu8abWwGgAAAABgHqzvrFpYDQAAAAAwD9Z5Vi2sBgAAAAAYWkUbkA1DFwAAAAAAAHZWAwAAAAAMrZJ1vrFaWA0AAAAAMA+0AQEAAAAAgIHZWQ0AAAAAMAfW+cZqYTUAAAAAwPAqldmk1VXVW7j0ne7efSYP3QbCagAAAACAte+DSTYuGvv+EIVsibAaAAAAAGAezLYNyCXd/XczfcJ2ElYDAAAAAAysMvue1VW1U5Kduvvq2T5p22wYugAAAAAAAMaB9RTHlH49yTVJvl1V/1VVJ1bVHitS+AqZeVhdVRuq6qiqurCqrquqL1XV8VW12zastWtVXVJVXVWvnkW9AAAAAACrbvPW6mmO5TsnyTEZBdZPSfKBJEcm+WBVrasXLL4yyTOT/GOS45Pcbfz5vlX1C919wxRrHZtk75UvEQAAAABgWNuwW3qvqjpvweeN3b34JYrp7p9dNPSWqvp4kj9L8qzxeXAzDaur6h5JnpHk1O5+7ILxzyd5VZLHJzlpmWv9TJJnJ/mjjEJvAAAAAIA1Yxt6Vm/q7vtt4+NeluQFSR6ZOQmrZ90G5AkZ/YHACYvGX5dRf5RDlrNIVd1kfM8/JTl1BesDAAAAAJgPs2sDciPd/f0klyfZa0VqXwGzDqsPSnJDRj1R/lt3X5fk/PH15TgqyV0z6qMCAAAAALDmzPgFiz/6rKpdkuyX5MrtXGrFzDqs3iejrejfnXDtsox6quy01AJV9VNJXpjk2O6+dOVLBAAAAAAY1qzer1hVt9rCpRdl1Cb63SvzHWy/Wb9gcdckk4LqJLluwZzvLbHGa5NckuQV0z68qo5IckSS7Jw9pr0dAAAAAGAVbe9+6YmeV1UPSPKvSb6YZPckv5zkoUk+nOTEWTx0W8w6rL4mya23cG2XBXMmqqpDkvxikgeNe6hMZfzmy41J8mO1T097PwAAAADAatnONtRbckaSuyd5SpJbJbk+ycVJnpvkFeOWzXNh1mH15UnuXlU7T2gFsm9GLUIm7qquqp0z2k393iRXVNUdF9yXJHuMxzZ19zdXvnQAAAAAgB1bd78zyTuHrmM5Zt2z+tzxM+6/cHDcvPs+Sc5b4t6bJ9k7ySMzSvo3H2eMrx8y/nz4ShYMAAAAALDqpuxXPaNd2IOa9c7qk5P8aZJnJ/nggvGnZdSr+m2bB6rqgCQ36+4Lx0PfSfK4CWvuneSvkvxTkjck+fiKVw0AAAAAsOrWYAI9hZmG1d19QVW9JsmRVXVqRi097pbkmUnOTHLSgunvT3L7jH9Fxj2q37F4zaraf/zl57r7RtcBAAAAAHZEa3G39DRmvbM6Ge2qvjTJERm19NiU0Rsmj+7uG1bh+QAAAAAAzLmZh9XdfX2S48fHUvP2X+Z6l2a974cHAAAAAFhjVmNnNQAAAAAAW7POt+gKqwEAAAAABlbjf9azDUMXAAAAAAAAdlYDAAAAAMyBWt8bq+2sBgAAAABgeHZWAwAAAAAMrbLut1YLqwEAAAAA5sD6jqqF1QAAAAAA82Gdp9XCagAAAACAObDOs2phNQAAAADAXFjnPas3DF0AAAAAAADYWQ0AAAAAMAfW975qYTUAAAAAwHxY52m1sBoAAAAAYGCVpNZ5Wi2sBgAAAACYB+s7qxZWAwAAAADMg3WeVWfD0AUAAAAAAEB199A1rIqq+mqSLwxdB6tqrySbhi4CmCk/57D2+TmHtc/POax9fs7Xn9t3995DF7GjOfDAA/us/zh7qnt2uflOH+nu+82opFW3btqA+AFZf6rqvLX0wwrcmJ9zWPv8nMPa5+cc1j4/5zCN9d0IZN2E1QAAAAAA82x9R9XCagAAAACA+bDO02phNWvZxqELAGbOzzmsfX7OYe3zcw5rn59zWKZ1nlVnw9AFwKx0t/8Ywhrn5xzWPj/nsPb5OYe1z885LFclNeWx3JWrNlTVUVV1YVVdV1Vfqqrjq2q3GX5DUxNWAwAAAACsba9M8ookn0ryjCRvT/LMJO+uqrnJiLUBAQAAAACYA1Nslp5izbpHRgH1qd392AXjn0/yqiSPT3LSyj95enOTmsP2qqrnVNXbq+qSquqqunTomoCVU1V3rqpjq+rsqvpqVX27qs6vqufO219bAlZOVe264L/trx66HmD7VdXuVfWnVXXB+L/nm6rqrKo6tGoWv0UHgHXvCRm1wz5h0fjrklyT5JDVLmhL7KxmLXlJkq8n+WiSPYctBZiBw5I8Pcm7krwtyfeTPDTJi5P8RlU9oLuvHbA+YDaOTbL30EUAK2P814z/b5IHJnlzkhOT7JrRb6LfmORuSf54sAIBYECVZEZ/bntQkhuSnLNwsLuvq6rzx9fngp3VrCUHdPetuvsXk1w+dDHAintHkv26+7e6+8Tufm13/2aSP0tyryRPHbY8YKVV1c8keXaSFwxcCrByfjbJ/0jyqu4+rLs3dvcJSX4+yeeT/PaQxQHAGrVPkk3d/d0J1y5LsldV7bTKNU1kZzVrRndfMnQNwOx093lbuHRykucmuecqlgPMWFXdJKO/lvhPSU5NcvywFQEr5Bbj849sLunu71XVpiQ7r35JADAfPvLRj/zzTW92k72mvG2Xqlr4++WN3b1x0Zxdk0wKqpPkugVzvjfls1ecsBqAHd1+4/OVg1YBrLSjktw1yWO3NhHYoZyT5JtJ/mj8jpkPZ/Sb46ckOTDJ7wxWGQAMrLsfMaOlr0ly6y1c22XBnMEJqwHYYY13Xj4/yQ8yJ28uBrZfVf1UkhcmOba7L62q/QcuCVgh3f2NqvqVJK9PcsqCS99O8tjuPm2QwgBgbbs8yd2raucJrUD2zahFyOC7qhM9qwHYsZ2Q5OAkR3f3RQPXAqyc1ya5JMkrhi4EmImrk3wiycuTPCbJ4Uk+m+SkqvrFIQsDgDXq3Ixy4PsvHKyqXZLcJ8mW2m6uOmE1ADukqnpRkiMz6sd13ND1ACujqg5J8otJfre7vz90PcDKqqqfTnJWkvd19//q7n/s7jdk9NLFK5K8bvw3pwCAlXNyks7o5eULPS2jdlxvW+2CtkRYDcAOp6qOSfK8JG+M3pawZlTVzhntpn5vkiuq6o5Vdccktx9P2WM8tudQNQLb7aiMemO+feFgd1+T5D0Z/bzvv/plAcDa1d0XJHlNksdU1alVdXhVHZ/R//c+M3PUVlNYDcAOZRxUvyDJm5Mc3t09bEXACrp5kr2TPDLJxQuOM8bXDxl/PnyI4oAVse/4PGn39E0XnQGAlfPsJH+Y5B4ZBdePT3Jikv+vu28YsK4fUX6Pz1pUVZ9Isnt37z90LcDKqaqjM3rp2luTHDpP/0EFtl9V3SzJoydc2jvJXyX5pyRvSPLx7v7MatYGrIyqemVGv1n+4+5+6YLxPZN8KqNd13t39/WDFAgADEpYzZpRVU/KD/+a8DOS7JTk+PHnL3T3WwcpDFgRVfX0JK9O8sUkz0+yOKi+srvft+qFATNXVfsn+XyS13T3kQOXA2yHqrp9ko8m+fGM+mP+R5JbZtQzc/8kT+/uvxqsQABgUMJq1oyqOiPJg7dw+czufsjqVQOstKp6U5KnLDHFzzmsUcJqWFuq6oAkRyd5eJKfSHJtkvOTnNDdpw5YGgAwMGE1AAAAAACD84JFAAAAAAAGJ6wGAAAAAGBwwmoAAAAAAAYnrAYAAAAAYHDCagAAAAAABiesBgAAAABgcMJqAAAAAAAGJ6wGAGAmqurSqjpjO+4/o6ouXbmKAACAeSasBgAAAABgcMJqAAAAAAAGJ6wGAAAAAGBwwmoAALZLVf1kVZ1SVVdV1beq6t1VdcAS83+hqv6lqr5ZVddV1cer6neW+az7V9WbquozVXVNVX27qv6jqn5t0by/rKquqjtNWOO2VfWDqvrb6b9bAABgVoTVAABss6raM8m/JXlMkrcm+ZMk1yT51yS7TZh/RJJ/SbJ7kj9L8vtJPpfkr6vqZct45K8luWuSU5I8a7zGLZOcWlVPXDDvdePzYRPWeEqSmyR5/TKeBwAArJLq7qFrAABgB1VVL0nynCSHdfcbF4yfkFGYfGZ3P2Q8dtskn09yanc/cdE6f5nkyCR36u5LxmNnJNm/u/dfMG+37v7Oont3TfKxJNd3990XjJ+VZP8kP9nd1y8Y/0ySHyycCwAADM/OagAAtsevJrkyyVsWjf/FhLm/nmTnJG+oqr0WHknendH/N/2FpR62MKiuql2r6lZJdk3ygSR3q6pbLJi+Mcltk/zygnselOROSd6wvG8PAABYLTcdugAAAHZod0hy7sKdy0nS3V+pqm8umnu38fn0Jdb7iaUeVlW3TvLiJI9OcusJU/ZM8q3x1ycnOSHJUzMKwzP++nu5cbgOAAAMTFgNAMBqqfH5yUm+soU5l2zx5qrKqN/13ZL8ZZLzklyV5Pok/zPJE7Pgbw5297VV9XdJfruqfiLJtRnt7n5Xd391+74VAABgpQmrAQDYHpckuVNV3WRRX+jbZrTLeaGLx+dN3b3U7uotuVeSeyc5trtfsPBCVR2+hXs2Jnl6Ri9VvCqjliFagAAAwBzSsxoAgO3xzoxadzx50fgfT5h7SpLvJnlhVd188cWq2qOqdl7iWZvD8Fo4WFX3TPJrk27o7o8nOSfJYRm1APliRruzAQCAOWNnNQAA2+OlGbXfeF1VHZjkk0kekuTgJJsWTuzuL1fV7yZ5fZJPV9Vbk3whyd5JfjqjlzXePcmlW3jWp8fr/1FV7ZrkoiR3TvLbSS5IcuAW7ts4fmaSvLC7b5j2mwQAAGZPWA0AwDbr7m9U1c8neUV+uLv6zCQPTfL+CfPfWFWfSfKHGYXMe2YUal+U5PlJrljiWddX1SOTvDyjth67JfnE+Ot7Z8th9f8e17d7kjdO9x0CAACrpbp76BoAAGBmxq1FvpLk3O7+f4euBwAAmEzPagAA1rrfSvLjGbUDAQAA5pSd1QAArElV9agkt09yTJIrk9yru69f8iYAAGAwwmoAANakqro0yT5JPpLk8O7+5LAVAQAASxFWAwAAAAAwOD2rAQAAAAAYnLAaAAAAAIDBCasBAAAAABicsBoAAAAAgMEJqwEAAAAAGJywGgAAAACAwf3//4wohKMHQd4AAAAASUVORK5CYII=\n", "text/plain": [ - "" + "
" ] }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[1;31mLoading data from a sequential run/already combined runs of experiment configurations.\u001b[0;0m\n", - "../mdpp_to_cave/a3c_lstm_seq\n" - ] - }, - { - "data": { - "text/html": [ - "\n", - "\n", - "
\n", - "
\n", - "
\n", - " \n", - "
\n", - "
\n", - "
\n", - "
\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
DefaultIncumbent
Quality-24.37-88.06
\n", - "
\n", - "
\n", - "
\n", - " \n", - "
" - ], - "text/plain": [ - "" - ] + "metadata": { + "needs_background": "light" }, - "metadata": {}, "output_type": "display_data" }, { "name": "stderr", "output_type": "stream", "text": [ - "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/pimp/evaluator/local_parameter_importance.py:268: RuntimeWarning: invalid value encountered in double_scalars\n", - " overall_var_per_tree = {p : [t / sum_var_per_tree[idx] for idx, t in enumerate(trees)] for p, trees in\n", - "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/pimp/evaluator/local_parameter_importance.py:402: UserWarning: Attempted to set non-positive top ylim on a log-scaled axis.\n", - "Invalid limit will be ignored.\n", - " ax1.set_ylim([min_y * 0.95, max_y])\n" + "/mnt/484A4CAB4A4C9798/GoogleDrive/Maestria-Drive/HiWi/mdp-playground/mdp_playground/analysis/analysis.py:566: UserWarning: FixedFormatter should only be used together with FixedLocator\n", + " plt.gca().set_xticklabels(tick_labels[0])\n" ] }, { "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute('style', 'box-sizing: content-box;');\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " var nentries = entries.length;\n", - " for (var i = 0; i < nentries; i++) {\n", - " var entry = entries[i];\n", - " var width, height;\n", - " if (entry.contentBoxSize) {\n", - " if (entry.contentBoxSize instanceof Array) {\n", - " // Chrome 84 implements new version of spec.\n", - " width = entry.contentBoxSize[0].inlineSize;\n", - " height = entry.contentBoxSize[0].blockSize;\n", - " } else {\n", - " // Firefox implements old version of spec.\n", - " width = entry.contentBoxSize.inlineSize;\n", - " height = entry.contentBoxSize.blockSize;\n", - " }\n", - " } else {\n", - " // Chrome <84 implements even older version of spec.\n", - " width = entry.contentRect.width;\n", - " height = entry.contentRect.height;\n", - " }\n", - "\n", - " // Keep the size of the canvas and rubber band canvas in sync with\n", - " // the canvas container.\n", - " if (entry.devicePixelContentBoxSize) {\n", - " // Chrome 84 implements new version of spec.\n", - " canvas.setAttribute(\n", - " 'width',\n", - " entry.devicePixelContentBoxSize[0].inlineSize\n", - " );\n", - " canvas.setAttribute(\n", - " 'height',\n", - " entry.devicePixelContentBoxSize[0].blockSize\n", - " );\n", - " } else {\n", - " canvas.setAttribute('width', width * fig.ratio);\n", - " canvas.setAttribute('height', height * fig.ratio);\n", - " }\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'width: ' + width + 'px; height: ' + height + 'px;'\n", - " );\n", - "\n", - " rubberband_canvas.setAttribute('width', width);\n", - " rubberband_canvas.setAttribute('height', height);\n", - "\n", - " // And update the size in Python. We ignore the initial 0/0 size\n", - " // that occurs as the element is placed into the DOM, which should\n", - " // otherwise not happen due to the minimum size styling.\n", - " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " rubberband_canvas.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " var cursor = msg['cursor'];\n", - " switch (cursor) {\n", - " case 0:\n", - " cursor = 'pointer';\n", - " break;\n", - " case 1:\n", - " cursor = 'default';\n", - " break;\n", - " case 2:\n", - " cursor = 'crosshair';\n", - " break;\n", - " case 3:\n", - " cursor = 'move';\n", - " break;\n", - " }\n", - " fig.rubberband_canvas.style.cursor = cursor;\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " evt.data.type = 'image/png';\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " evt.data\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", - "mpl.findpos = function (e) {\n", - " //this section is from http://www.quirksmode.org/js/events_properties.html\n", - " var targ;\n", - " if (!e) {\n", - " e = window.event;\n", - " }\n", - " if (e.target) {\n", - " targ = e.target;\n", - " } else if (e.srcElement) {\n", - " targ = e.srcElement;\n", - " }\n", - " if (targ.nodeType === 3) {\n", - " // defeat Safari bug\n", - " targ = targ.parentNode;\n", - " }\n", - "\n", - " // pageX,Y are the mouse positions relative to the document\n", - " var boundingRect = targ.getBoundingClientRect();\n", - " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n", - " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n", - "\n", - " return { x: x, y: y };\n", - "};\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * http://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " var canvas_pos = mpl.findpos(event);\n", - "\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " var x = canvas_pos.x * this.ratio;\n", - " var y = canvas_pos.y * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We want\n", - " * to control all of the cursor setting manually through the\n", - " * 'cursor' event from matplotlib */\n", - " event.preventDefault();\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.which === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.which;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.which !== 17) {\n", - " value += 'ctrl+';\n", - " }\n", - " if (event.altKey && event.which !== 18) {\n", - " value += 'alt+';\n", - " }\n", - " if (event.shiftKey && event.which !== 16) {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k';\n", - " value += event.which.toString();\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(msg['content']['data']);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " var manager = IPython.notebook.keyboard_manager;\n", - " if (!manager) {\n", - " manager = IPython.keyboard_manager;\n", - " }\n", - "\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], + "image/png": "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\n", "text/plain": [ - "" + "
" ] }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] + "metadata": { + "needs_background": "light" }, - "metadata": {}, "output_type": "display_data" - }, + } + ], + "source": [ + "# IMPORTANT: The 2-D plots here are for the 1st experiment in the experiments dict above\n", + "# 2-D heatmap plots across runs: Training runs: with std dev across the runs\n", + "# There seems to be a bug with matplotlib - x and y axes tick labels are not correctly set even though we pass them. Please feel free to look into the code and suggest a correction if you find it.\n", + "mdpp_analysis.plot_2d_heatmap(list_exp_data, save_fig)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "scrolled": false + }, + "outputs": [ { - "name": "stdout", + "name": "stderr", "output_type": "stream", "text": [ - "\u001b[1;31mLoading data from a sequential run/already combined runs of experiment configurations.\u001b[0;0m\n", - "../mdpp_to_cave/a3c_del\n" + "/mnt/484A4CAB4A4C9798/GoogleDrive/Maestria-Drive/HiWi/mdp-playground/mdp_playground/analysis/analysis.py:546: UserWarning: FixedFormatter should only be used together with FixedLocator\n", + " plt.gca().set_xticklabels(tick_labels[0])\n" ] }, { "data": { - "text/html": [ - "\n", - "\n", - "
\n", - "
\n", - "
\n", - " \n", - "
\n", - "
\n", - "
\n", - "
\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
DefaultIncumbent
Quality-90.19-98.51
\n", - "
\n", - "
\n", - "
\n", - " \n", - "
" - ], + "image/png": "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\n", "text/plain": [ - "" + "
" ] }, - "metadata": {}, + "metadata": { + "needs_background": "light" + }, "output_type": "display_data" }, { "name": "stderr", "output_type": "stream", "text": [ - "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/pimp/evaluator/local_parameter_importance.py:268: RuntimeWarning: invalid value encountered in double_scalars\n", - " overall_var_per_tree = {p : [t / sum_var_per_tree[idx] for idx, t in enumerate(trees)] for p, trees in\n", - "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/pimp/evaluator/local_parameter_importance.py:402: UserWarning: Attempted to set non-positive top ylim on a log-scaled axis.\n", - "Invalid limit will be ignored.\n", - " ax1.set_ylim([min_y * 0.95, max_y])\n" + "/mnt/484A4CAB4A4C9798/GoogleDrive/Maestria-Drive/HiWi/mdp-playground/mdp_playground/analysis/analysis.py:566: UserWarning: FixedFormatter should only be used together with FixedLocator\n", + " plt.gca().set_xticklabels(tick_labels[0])\n" ] }, { "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute('style', 'box-sizing: content-box;');\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " var nentries = entries.length;\n", - " for (var i = 0; i < nentries; i++) {\n", - " var entry = entries[i];\n", - " var width, height;\n", - " if (entry.contentBoxSize) {\n", - " if (entry.contentBoxSize instanceof Array) {\n", - " // Chrome 84 implements new version of spec.\n", - " width = entry.contentBoxSize[0].inlineSize;\n", - " height = entry.contentBoxSize[0].blockSize;\n", - " } else {\n", - " // Firefox implements old version of spec.\n", - " width = entry.contentBoxSize.inlineSize;\n", - " height = entry.contentBoxSize.blockSize;\n", - " }\n", - " } else {\n", - " // Chrome <84 implements even older version of spec.\n", - " width = entry.contentRect.width;\n", - " height = entry.contentRect.height;\n", - " }\n", - "\n", - " // Keep the size of the canvas and rubber band canvas in sync with\n", - " // the canvas container.\n", - " if (entry.devicePixelContentBoxSize) {\n", - " // Chrome 84 implements new version of spec.\n", - " canvas.setAttribute(\n", - " 'width',\n", - " entry.devicePixelContentBoxSize[0].inlineSize\n", - " );\n", - " canvas.setAttribute(\n", - " 'height',\n", - " entry.devicePixelContentBoxSize[0].blockSize\n", - " );\n", - " } else {\n", - " canvas.setAttribute('width', width * fig.ratio);\n", - " canvas.setAttribute('height', height * fig.ratio);\n", - " }\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'width: ' + width + 'px; height: ' + height + 'px;'\n", - " );\n", - "\n", - " rubberband_canvas.setAttribute('width', width);\n", - " rubberband_canvas.setAttribute('height', height);\n", - "\n", - " // And update the size in Python. We ignore the initial 0/0 size\n", - " // that occurs as the element is placed into the DOM, which should\n", - " // otherwise not happen due to the minimum size styling.\n", - " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " rubberband_canvas.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " var cursor = msg['cursor'];\n", - " switch (cursor) {\n", - " case 0:\n", - " cursor = 'pointer';\n", - " break;\n", - " case 1:\n", - " cursor = 'default';\n", - " break;\n", - " case 2:\n", - " cursor = 'crosshair';\n", - " break;\n", - " case 3:\n", - " cursor = 'move';\n", - " break;\n", - " }\n", - " fig.rubberband_canvas.style.cursor = cursor;\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " evt.data.type = 'image/png';\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " evt.data\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", - "mpl.findpos = function (e) {\n", - " //this section is from http://www.quirksmode.org/js/events_properties.html\n", - " var targ;\n", - " if (!e) {\n", - " e = window.event;\n", - " }\n", - " if (e.target) {\n", - " targ = e.target;\n", - " } else if (e.srcElement) {\n", - " targ = e.srcElement;\n", - " }\n", - " if (targ.nodeType === 3) {\n", - " // defeat Safari bug\n", - " targ = targ.parentNode;\n", - " }\n", - "\n", - " // pageX,Y are the mouse positions relative to the document\n", - " var boundingRect = targ.getBoundingClientRect();\n", - " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n", - " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n", - "\n", - " return { x: x, y: y };\n", - "};\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * http://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " var canvas_pos = mpl.findpos(event);\n", - "\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " var x = canvas_pos.x * this.ratio;\n", - " var y = canvas_pos.y * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We want\n", - " * to control all of the cursor setting manually through the\n", - " * 'cursor' event from matplotlib */\n", - " event.preventDefault();\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.which === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.which;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.which !== 17) {\n", - " value += 'ctrl+';\n", - " }\n", - " if (event.altKey && event.which !== 18) {\n", - " value += 'alt+';\n", - " }\n", - " if (event.shiftKey && event.which !== 16) {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k';\n", - " value += event.which.toString();\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(msg['content']['data']);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " var manager = IPython.notebook.keyboard_manager;\n", - " if (!manager) {\n", - " manager = IPython.keyboard_manager;\n", - " }\n", - "\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], + "image/png": "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\n", "text/plain": [ - "" + "
" ] }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] + "metadata": { + "needs_background": "light" }, - "metadata": {}, "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[1;31mLoading data from a sequential run/already combined runs of experiment configurations.\u001b[0;0m\n", - "../mdpp_to_cave/a3c_lstm_del\n" - ] - }, + } + ], + "source": [ + "# 2-D heatmap plots across runs: Evaluation runs: with std dev across the runs\n", + "mdpp_analysis.plot_2d_heatmap(list_exp_data, save_fig, train=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ { "data": { - "text/html": [ - "\n", - "\n", - "
\n", - "
\n", - "
\n", - " \n", - "
\n", - "
\n", - "
\n", - "
\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
DefaultIncumbent
Quality-83.95-96.01
\n", - "
\n", - "
\n", - "
\n", - " \n", - "
" - ], + "image/png": "iVBORw0KGgoAAAANSUhEUgAACbUAAAFACAYAAACBNgMyAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAAEAAElEQVR4nOzdd5xcdb3/8ddnyu6mdwKEEppSpCiIWFCxi17Fn9dy7RV7R6/lekWuWFFRURBUepemIEhvoQcICemkl02y2WwvM3PO9/fHOTNzZubM9pLdvJ955LFnTv1O/Z7yOZ+POecQERERERERERERERERERERERER2R0kRrsBIiIiIiIiIiIiIiIiIiIiIiIiInkKahMREREREREREREREREREREREZHdhoLaREREREREREREREREREREREREZLehoDYRERERERERERERERERERERERHZbSioTURERERERERERERERERERERERHYbCmoTERERERERERERERERERERERGR3YaC2kRGgZl9wsxc+P8Tw7ytMyPbev1wbktERGRPob5cRERk7FI/LiIiMrapLxcRERnb1JeLSF8pqE1Exjwzm2Rm3zSzBWa23cy6zGy9mV1rZm8d7faJiIhIPDObaGavNLOvmNklZrbEzHI6ySAiIrL7M7MDzOxzZnZl2Ie3mFnGzHaY2cNmdpaZHTDa7RQREZH+MbMZZlYfOTZ3ZjZ/tNslIiIilSzwDjO7ysxWmVmbmWXNrMHMHjGzn5rZIaPdTpGBSo12A0REBsPMXgr8HTi4bNIB4f/3m9mVwKecc5mRbp+IiIj0aCMwc7QbISIiIv1jZjcD7wIsZvLs8P+rge+Y2f84584ZweaJiIjI4PwGmDvajRAREZGemdls4Hrg9TGTZwGvDP9/y8x+6Jz75Qg2T2RIKKhNRMYsMzsQuJ3iAfYTwBVAA3A0cDpBh/1hwAEfHYVmioiISHXJsscbgBpg71Foi4iIiPTdSygGtD0J3AesBFqA/YD3EgS11QK/MrNa59zZo9FQERER6TszezPwCcAHMkDdqDZIREREYplZiuA6+QnhqC7gMmARsAvYH/gP4DUE59x/YWZtzrk/jUJzRQZMQW0iMpadSzGg7W/AZ51zfvj4ajP7M/AgQca2j5jZNc6520a+mSIiIlLFLcAKYCGw0DnXYGaXAB8f1VaJiIhIb7qAPwJ/cM6tiJn+WzP7BkGmF4Azzex659zKEWuhiIiI9IuZTQT+HD78I0FW1gNHr0UiIiLSg/+iGNC2ETjZObe+bJ5fmtlngQvDxz82swudc7mRaqTIYCVGuwEiIgNhZscCp4UPNwBfigS0ARB23F+IjDpzRBonIiIifeKc+7hz7qfOuX875xpGuz0iIiLSZyc7575cJaANAOfcb4EbwocpgizqIiIisvv6CXAQsBn4wSi3RURERHr21sjwz2MC2gBwzl1EcFM5wGzgiOFumMhQUlCbyDAws3ea2T/NrN7MusxsnZldaWavHMC6aszs02b2DzPbGK6vycyeM7Nfm9n8IWjvBDN7j5n90cweN7OdZpY1s2Yze97Mzg+DyKot/3kzc+H/b/Zxm/+ILDOQzvMDkeELnXNdVea7HVgdDp9gZgcPYFsiIrKHUV/ep20Oti8XEREZFurH+7TNQfXjzrldfZz1+sjw0f3djoiI7JnUl/dpm0N6TG5mJwJfCx9+xTnXOth1iojInkt9eZ+2Odi+fK/I8Kpe5o1mTZ80gG2JjBoFtYkMITNLWlAy65/AOwlKY9YSpOj+EPCwmX2nH+s7AVgO/IWg5vV+4fqmEZwM/iawwsw+N8imLwVuBL4InAjMJLiLeipwJPB54Fkz+2mV5a8E2sLhT/e2MTObB5waPnzYObdsAG1+S2T4jmozOecc8O/IqLcNYFsiIrKHUF8OjFxfLiIiMqTUjwO7Xz8evSA+YRi3IyIi44D6cmAU+nIzSxO8RgngFufcTYNZn4iI7LnUlwMj15dviwwf1su8+ekepQFuIru91Gg3QGSc+T3w8XA4A1wKPAz4BB3gp4FfADf3tqIwUv1uYCKQD8y6kyD19wTglcBHw+kXmFm3c+6SAbZ7AtAI3AU8E24jC8wDXga8H0gD3zOz7c65c6MLO+dazewq4HTgSDN7tXNuQQ/b+ySQDIcv6m9jzSxBsAMBkAMW9bLIU5Hhl/R3eyIiskdRXz4CfbmIiMgwUT+++/Xj0WPw2FIoIiIiEerLR6cv/y5BYEAr8OUhWJ+IiOy51JePXF9+C/CRcPi7ZnZbXAlSM/sscEL48HLnXOMAtycyKixIYiQig2VmJwMPhg+bgDc55xaWzfNi4H5g78joT5Z3sGY2BXge2D9c12nOuQditnkocA9wANAOzHfONZTNcybwo/DhKc65+2PW8zbgbudcrspzO5AgG9rhBAe288rTj5vZyyjW477UOfeJKusyYA0wP3xu+zrnOuPmrcbMDqB4Mny9c25+L/OfAtwbPrzHOfem/mxPRET2DOrLR64v70l4J1/+xEfs8xURESmnfnz36MfLtpUCFoftBniXc+6fw7EtEREZ+9SXj05fHpY7e4Yg683XnHO/j0xbR5BZB+Ag59y6gW5HRETGP/XlI9uXh+u5AXhPOKoLuAx4FthF8Nq9C3hNOP0m4GPOuTZExhCVHxUZOt+KDH+9vJMGcM6tAD7Th3V9lqCjgaBzqeikw/WtJojkhqD+9el9b27Jeu6o1kmH09cTpFsFmAK8O2aep4Enw4fvM7OpVVb3JoJOGuDKAR5wT48MN1SbKWJnlWVFRESi1JePXF8uIiIy1NSP7379+BkUA9qeA24bxm2JiMjYp758hPvysCLKXwgC2p4CzhvoukRERFBfPqJ9uQuyV70P+ClBoF0dwfP/E3A18EuCgLanCUrBvlcBbTIWKahNZAiYWS3w9vDhNuCKavM6524DequL/dHw78re7mJ2zt0LbAkfvqX31g7YI5HhV1SZ54Lw70Tgw1Xm+Wxk+MIBtmVyZLirD/NHdwamDHCbIiIyjqkvLxipvlxERGTIqB8v2G368TBj+v+FD3PA551z/nBtT0RExjb15QUj3Zd/EXgV4AGnq68WEZGBUl9eMKJ9uXPOA34FnAV0V5ntZQSlxl85mG2JjJbUaDdAZJw4FqgJhx8IO5Ce3AMcETfBzKYBx4QPt5nZaX3Yfj6qOnadfWFmewEfI+jsjwRmEHS4cfarMv4a4DfANIIO+fyybcyhGLn+hHPuuYG2V0REZIipLw+oLxcRkbFI/Xhgt+jHzexw4HqK5x2/75x7dDi2JSIi44b68sCI9eVmdgDws/Dhuc65Zwa6LhEREdSX543ocXlYNvWacHv3E/TtjxMkfDmAIJPbDwgytt1jZh90zt0ymG2KjDQFtYkMjX0jw6v7MH9P8+xPMYviyeH/vprRj3kLzOwDwJ8JOry+iE2X6pzrMLPLgS8DLzWzl4WpVvM+RnGH5qKBtDUUTY1a14f5J0SGW6vOJSIiezL15YxoXy4iIjKU1I+ze/TjZnYQcDcwKxx1rnPuV8OxLRERGVfUlzPiffn5BBVR1gM/GuS6RERE1Jczsn15GNB2G8Fr9XfgA2VZV1cDPzOze4AHCa6pX25mL3LO1Q9m2yIjSUFtIkMjWg6zow/zt/cwra+dZZx0fxcws9cCV1HcOXia4AT0C0AzpalKbwr/JntY5Z8JOmoIItC/EJmWr5HeRhA1PlBNkeHZfZh/VmS4qdpMIiKyR1NfXjQSfbmIiMhQUj9eNGr9uJntD9wLzAtHXeCc+8ZQb0dERMYl9eVFw96Xm9mHgVPDh190zvX0eoqIiPSF+vKikTou/zVBm33ga9XKiDvnnjCzS4DPAVOATwA/H+S2RUaMgtpEhkY0c1i1NKRRk/q4rsuccx8fWJP67EyKnfTpzrnYqHAz66nNBc65JWa2AHg18CEz+1YYlX4ycHg429XOubbqa+nVJoK0qROAeWaWcs7lepj/wMjwykFsV0RExi/15aER6stFRESGkvrx0Gj142a2L0FA2/xw1N+ALw7lNkREZFxTXx4aob48f0G9HniZmb2synzRoIIvm1lTOHyRc27bILYvIiLjj/ry0Ej05WGW9CPDh0udc1t6WeRugqA2gBMHul2R0aCgNpGhEe0oDu3D/D3NszkyXK0e95AwsxqKKVufqtZJhw7sYVq5Cwg66qnA+4FLKB4oA1zYj3VVcM75ZrYUOJ7gd+xYYGEPi5wQGV4ymG2LiMi4pb681LD25SIiIkNM/XipEe3HzWxvgoC2/Ot6BfBZ55wbyu2IiMi4pr681HD35Rb+3Rv4vz4u863I8K2AgtpERCRKfXmp4e7Lo+VeW/owf3NkuE/BeSK7i0Tvs4hIHywCMuHw68ysp5SjAG+sNsE51wAsDR+eZGaxNbmHyCyKwa0v9DLvW/ux3r8DO8Phz5rZdOB94eNnnXNP9WNd1fy7L20zMyubfscQbFtERMYf9eWlRqIvFxERGSrqx0uNWD9uZnOAe4AXh6OuBT5RreyJiIhIFerLS+mYXERExhr15aWGuy+PBrLt34f5owF5O6vOJbIbUlCbyBBwznUD/wofzgU+VG1eM3s7cEQvq7w0/DsR+O6gG1hdtKb5IdVmMrMpwDf6ulLnXBfF5/Aq4GyCUqEAPUW498d1keHPmVldlfneTjHa/ynn3Joh2r6IiIwj6stLjVBfLiIiMiTUj5caqX7czGYSlDDJlzy5EfiIc84bqm2IiMieQX15qeHuy51zr3fOWW//gfWRxQ6KTHt2sG0QEZHxRX15qRE4Ll8NdIXD+5vZq3qZ/4ORYQXHy5iioDaRofPryPDvzOy48hnM7DDgr31Y1x8pHjB+18y+bWZVv69mNs3Mvmpmb+pPg51zzcCq8OEJZvaemHVPBq6nb1HeUX+ODH8x/NsBXNnP9cRyzi0Cbg4fHgCcV/4amdkBwPmRUWcOxbZFRGTcUl9ealj7chERkSGmfrzUsPbjZjYNuBM4Jhx1C/BB51xuKNYvIiJ7JPXlpXRMLiIiY4368lLD1pc75zoJjsPzLg2vi1cws+9TzIzXTWniGJHdXqr3WUSkL5xzD5vZnwg6pRnAY2Z2KfAw4AMnAp8mqFN9M3BaD+tqN7PTgAcIam3/kiAb2Q0E6VbbwvEHh+t9PVADfHQATf8D8Ptw+O9mdmXY5lbgJcAnCOpyXwZ8rK8rdc6tNLP7gFMio68Ldw6GyteBVxJE/H8aeImZXU6QNvVo4HMEaWMBrnTO3VZtRWZ2CfDx8OGPnXNnDmE7RURkDFBfXvEchr0vN7M3AG8oG/3SyPCnY05EnOOca4pZ1yWoLxcR2WOpH694DsPdj98OHB8ObwGuAt5hZj0t0+GcuzNugvpxERFRX17xHEbi/PqQUV8uIiLqyyuew3D35d8H3gzMJKhatsTMrgAeAzoJksK8D3hFZJkfO+c2xa3MzO4HXhc+/KRz7pIhaqfIoCioTWRofRWYQtBh1gKnh//zfOA7wA566KgBnHPPmtmJwNUEF3cPCZetphtoGECbzyPozD5MkL3xo1R2+LcAn6cfHXXoAko76iEtV+acWx+mqP07wU7LKyjtmPOuAj41lNsWEZFxS315qWHty4HXAj/oYfpHYsb9BWga4naIiMj4oH681HD246+MDO8LXNuHZdYD84ewDSIiMv6oLy813MfkIiIiQ019ealh68udc2vM7M3ANcBhBK/7F8L/5XLAmc65nw3V9kVGisqPigwh55znnPsY8B/AbQQdcjewgaDDfY1z7lf9WN8Kgjuf301Qd3sl0AJ4BBdzFxFEhX8C2Mc5d8cA2uyccx8hqG1+X7jeDLAJuBX4gHPutDCNaX/dHRle6px7ZADr6JFz7hmCciffAh4l2FnpBjYSpIJ9u3Puw865TC+rmhgZ3jHU7RQRkbFBfXmFYe/Lh5D6chGRPZz68Qrqx0VEZExRX15BfbmIiIwp6ssrDGtf7px7muA6+ceBm4B1BCVOcwSVzR4Dfg682Dl3di+rU18uuyVzzo12G0RknDKzz1CMOP+Gc+7cUWxOj8xsC7APsBU41DnXMcpNEhERGXXqy0VERMYu9eMiIiJjm/pykT2Xmb2MICjoeOBFwByCUostwHLgX8D5zrnGHtYxlyCr1TsJyhB2As8TBAb91SlIQGTYjZW+3MwmA41AGngWeJl+I2R3oaA2ERk2ZvYUwQ53J7BfTzvXo8nMjgKWhA+/4Jy7YDTbIyIisrtQXy4iIjJ2qR8XEREZ29SXi+y5zOw84EuRUV1AlqC8YF4D8C7n3KMxyx8P/BuYFY5qA+qAVPj43+GyvVU5EpFBGEN9+TsIstJBUAWt3xnvRIaLyo+KyLAws3cRdNIAV+6unXToTeHf1cBfRrMhIiIiuwv15SIiImOX+nEREZGxTX25yB7vCeDbwCuBGc65Cc65qQRBbR8nKA04G7jZzKZFFwwf30oQ0LYceLlzbgowCfgyQXDcW4FzR+apiOyZxmhf/oAC2mR3k+p9FhGR3pnZBOB1BL8rxxLsbENQc/xno9WuPnpj+PeHzrncqLZERERklKgvFxERGbvUj4uIiIxt6stFJMo5d1mV8W3AZWZWT5BtbS+C8qJXRmY7A9ibIDPUqc65teGyGeCPZjYV+Clwupmd65xbOXzPRGTPMU768u+OaitEYqj8qIgMCTObD6yNmfRN59xvR7g5IiIi0k/qy0VERMYu9eMiIiJjm/pyEemPMDCtOXz4XefcLyLT1gMHABc75z4Vs+xkYCswGTjLOfejEWiyyLinvlxkeKj8qIgMhybgUeC96qRFRETGpCbUl4uIiIxVTagfFxERGcuaUF8uIj07OTL8Qn7AzF5MENAGcHvcgmG2t4fCh28ZltaJSBPqy0WGhDK19dHs2bPd/PnzR7sZIiIyxixcuLDBOTdntNuxp1M/LiIiA6W+fPegvlxERAZC/fjuQ325iIgMhPryIjOrBfYhKDd6FjADWA28xDnXHc7zXuDv4SJHOueWVVnXLwlKI7Y456b1tm314yIiMlCD7ctTQ9mY8Wz+/Pk89dRTo90MEREZY8JU3zLK1I+LiMhAqS/fPagvFxGRgVA/vvtQXy4iIgOhvhzMrAuojZm0APhQPqAttG9keHMPq81Pm2pmk8PsbVWpHxcRkYEabF+u8qMiIiIiIiIiIiIiIiIiIiK7n3pgG9AeGXcf8HXn3IayeadEhjt6WGd02pS4GczsdDN7ysye2rFjR3/aKyIiMmQU1CYiIiIiIiIiIiIiIiIiIrKbcc7Nd87t7ZybDMwFzgCOA54ws7OGcbsXOudOcM6dMGeOKsCKiMjoUFCbiIiIiIiIiIiIiIiIiIjIbsw5t90592vgbYADfmhm74zM0hoZntjDqqLTWqvOJSIiMsoU1CYiIiIiIiIiIiIiIiIiIjIGOOeeAB4OH54embQlMjyvh1Xkp7U459qGsm0iIiJDSUFtIiIiIiIiIiIiIiIiIiIiY8fm8O+hkXFLIsMv6WHZ/LSlQ9oiERGRIaagNhERERERERERERERERERkbHj4PBvtHzoSmBDOPy2uIXMbBJwcvjwzuFpmoiIyNBQUJuIiIiIiIiIiIiIiIiIiMgoM7OkmVkv87wRODF8eH9+vHPOAZeFDz9oZvNjFv8SMBnwgCsH214REZHhpKC23cC2n/+CZYcfMdrNEBERkX5yvs+vP/BOHrvhmtFuioiIiAyA8zyu/I8388eP/edoN0VEREQG6JMXP8Ep59w/2s0QEREZKvsDz5jZ58zs4GiAm5ntb2bfBW4BDGgEflu2/DlAPTARuM3Mjg+XrTGzLwD/F853oXNu5TA/lwHbdeMqNn33odFuhoiIjLLUaDdAoPGSS0a7CSIiIjIAvu8DsOC6KzjpvR8c5daIiIhIf7muLuon1kJ312g3RURERAbovhU7RrsJIiIiQ+1Y4IJwOGNmLcAEYFJknrXAe51z9dEFnXPNZvZO4N/AkcBTZtYK1AHpcLY7gW8MY/sHrf2J+t5nEhGRcU+Z2kREREQGzBWG2rtzo9gOERERGZCETouIiIiMab7HFemzeXVi8Wi3REREZKhsAd4H/BF4CmgAphJc198A/BP4DHCUc+6ZuBU45xYCRxFkcVtFEMzWDjwMfBZ4u3Oue3ifhoiIyOApU5uIiIjIADm/GNR24zOb+ehJB45ia0RERERERET2LLn2Rl6TfJ6jEuuB7452c0RERAbNOZcB/h7+H8x6tgHfDP+LiIiMSbolWURERGSAXCRTW11Ku1UiIiJjjnORQdfDjCIiIrI76s55APjYKLdEREREREREhpquvoqIiIgMVCRTW206OYoNERERkQGJBLLlMqq8IiIiMtZ4XhDU5hTUJiIiIiIiMu4oqE1ERERkgJSpTUREZGyLJmfLdiuoTUREZKzxPR8A5VsVEREREREZf3T1VURERGSgnDK1iYiIjG2RTG0KahMRERlzvMJxuTK1iYiIiIiIjDcKahMREREZIBcJaksndAJdRERkzIn05crUJiIiMvb4Kj8qIiIiIiIybimoTURERGSAokFtKnUiIiIyBkX68lxGQW0iIiJjTXcuy96ve4Ar5r1ztJsiIiIiIiIiQ0xBbSIiIiIDFA1q853C2kRERMacaF/ue6PYEBERERmIlmzQf/95/gdGuSUiIiIiIiIy1BTUNoruW7Gd9u5c4bHTxXAREZGxpSSobRTbISIiIgMTzbqqzlxERGTM8b0soPKjIiIiIiIi45GC2kbJuoZ2Pnnxk3znhueKI31/9BokIiIi/aZMbSIiImNb6c1l6stFRETGGl/n1EVERERERMYtBbWNkrYwQ9uaHe3FkboYLiIiMqa4yMlznUgXEREZgyIlR5WpTUREZOxxfq73mURERERERGRMUlDbKDGD1yQWc/uudxZHKqhNRERkTPlXQzO/+vxP6KibiJfViXQREZEx56HfFgadMrWJiIiMOc4rBqjvas+MYktERERERERkqCmobZQYxueS/ywdqaA2ERGRMeXiHW0ANE6fg5dTUJuIiMiYs/6R4rAytYmIiIw5vhccizuMd/9xwSi3RkRERERERIaSgtpGiVlwoB2l0+ciIiJjixcGpCd8T0FtIiIiY5xzKiUuIiIy1viRTG0bGjtGsSUiIiIiIiIy1BTUtjtRpjYREZExJRdmdEk4Hz+XHeXWiIiISP8VbzbTIbmIiMjYk/O93mcSERGRMWth/VOj3QQRERlFCmobRbX+gXT7LymO8HVXuIiIyFiSC69+m+8rU5uIiMgYp0xtIiIiY49zCmoTEREZz+5ef89oN0FEREZRarQbsKcyg3ne59nhAZwejNRt4SIiImNKsfyoMrWJiIiMRSWH4TokFxERGXM8T0FtIiIi45n1PouIiIxjytQ2SiyuC1ZQm4iIyJiSz9SWcD6+p0xtIiIiY45Fy48qU5uIiMhY4yuoTUREZFyLvaYuIiJ7DAW1jRJTTJuIiIxjZub68f++mOXP7OOyh47G88vLZ2ozB77Kj4qIiIw9JZnadFAuIiLjk5lNNbP/NrNHzGyHmXWb2SYzuy88/p5eZbkp4fTFZtZmZs1m9qSZfcvMakb4acTy/CCozemCt4iIyLiUUDiDiMgeTeVHdys6gS4iIuPGtl6mp4GZ4fCTPcyXBRp7mD6qkWRephPSk3BmytQmIiIyxjkFtYmIyDhkZqcAVwNzw1EZoAOYF/5/PXAz8GzZcgcC9wPzw1EdQC1wQvj/w2b2RufcrmFsfq+cr0xtIiIi45oO1UVE9mgKbd6d6AS6iIiME865vXv6D/w0Mvtfe1jVI72sa93wPpOe5bwsAM7AV8UyEREZJ/aUjKsAODj41A0c/ckVCmoTEZFxx8xeDdxGENB2I/ByoM45NwOYBJwInA00ly2XAv5JENC2FXizc24SMBH4INAKvBS4YkSeSA98BbWJiIiIiIiMW8rUNkpiz5XrariIiOw5Ph3+fdg5t2JUWzIIntWGQ4Zz6sdFRGTc2CMyruZN3b8dUKY2EREZX8xsInAZMAH4g3Puq9HpzrkOgn48ri//OHB0OPxe59yj4TI+cK2ZJYCrgFPDbG33DNPT6JXne5BQEhcREZHxKuGUo0dEZE+mXmCU+HEny3UCXURE9gBm9irgiPDhX0azLYOR3dZOLgxqc6gbFxGR8WNPybgasMKQgtpERGSc+ShwMFAPfKefy348/HtfPqCtzDXA2nD4YwNr3tDwPd1gJiIiMt6c/djZhWEz62FOEREZ7xTUNkriY9p0Al1ERPYI+SxtzcD1o9mQwXA5hxceUE+pmYWvjKsiIrLnGBcZV6Esq4uOyUVEZHzJB5td75zr6utCYYa3V4cPb4+bxwUnsu8IH75lwC0cAs6F5Ud1wVtERGTcuGbFNYVh9fAiIns2BbWNkthMbSIiIuOcmU0G3h8+vDosd9KTo8xsiZl1mFmbma0ws4vM7KXD3NTeGXjhEfUr555GeybLwvU9VVgTEREZ+8ZLxtWCyKG5SomLiMh4YWa1wAnhw4VmdoCZXWhmG80sY2bbzOyfZvaOmMWPoHjdYEkPm8lP29vMZvYw37Dy80FtIiIiMj7pkrqIyB5NQW2jJDamTYFuIiIy/n0QmBwO9+VC+GyCE+qdQC3wIuAzBCflfzIsLewjS1ghqO1Dr5rEFY9u4L3nP0pbd240myUiIjLcxkXGVYANGy+mYVp7cYQOyUVEZPyYD9SEwwcTBKB9FtgLaA//vhO4NbxxLJoEZd/I8OYethGdtm/VuYZZvvyounEREZHxyZSrTURkj6agtlHi4g6zFdQmIiLj32fCv4uccwt7mG8V8B3gxUCdc24WMAl4K7CQIOv4D8zsW8PZ2B4Z5BLRh0E/7nnqz0VEZHwaVxlXgVWrfsKyg7YXHitTm4iIjCMzIsP/A2SB9wGTnXMzgAMpBqd/BvhGZP4pkeGe+vrotClxM5jZ6Wb2lJk9tWPHjr62vV+8YcrU5jyHr5vWRERERp05BbWJiOzJFNQ2ShLt2ytH+jqBLiIi45eZHQW8InzYY5Y259yVzrlfOedWOuey4biMc+5O4DXAk+GsZ5rZtCrbG9aT584HP3Iz+8FWB0BCe1ciIjJ+jZuMq3GcbjQTEZHxI1E2/Gnn3N8jx9cbCPr1ReE83zez1FA3wjl3oXPuBOfcCXPmzBnq1QeG6Zz6ziuWsuVHjw7LukVERKQfFNMmIrJH02XXUZLq2FYxTifQRURknMtnaesCrhjoSpxzXcD3w4eTgTdWmW94T577pf32z+oOCrY79FsSERHZXYxoxtWRyO4SpWNyEREZR1ojw6ucczeXz+CCFKXnhA9nAcfHLDuxh21Ep7VWnWuY+d2ZYVlv17LGYVmviIiI9I/pUF1EZI+moLZR4sd1wOqURURknDKzGuAj4cMbnHNNg1xl9Hbpgwe5roGpcuFblctERGQ8GumMq+Eyw57dpZ598MNTIwpqExGRcWRzZHh5D/MtjQwfGP7dEhk3r4dlo9O2VJ1rmNXe81QwoNJkIiIi45T6eBGRPZmC2kZJ9Fx5/czZPPqSl6KoNhERGcfeTVCCDPpWrmy319TZFDveqT8XEZHxaUQzro6E7czlW3Ye1/FfwQgFtYmIyDjhnGukNLCtmuhV4nxHuAzI3671kh6WzU+rD7c3KjbacYDOrIuIiIxXpqA2EZE9moLaRomLdMCf+uEv+f6XvqMT6CIiMp7lL4SvBh4YgvWdFBleOwTr67eOTEfs+NhsrCIiImPYuMy4CuxiBgDLORJQpjYRERl37gz/HtHDPEdGhtcCOOc6gAXhuLfFLWRmRlBWPLqdUbFt6rEju8GG1XDdxyDXPbLbFRER2UMllI1VRGSPpqC2URI9Wd5ZNyE/cpRaIyIiMnzM7ADgTeHDv7lerhiHJ8d7ml4LnB0+bAfuGXQjByBFMna8r/5cRETGn3GXcTXK8rld1IeLiMj4cnH491AzO618opklgDPCh5uBpyOTLw3/nmJmr6DS+ygGpl82+KYOnOv5FMLQu/kLsPQW2Px07/OKiIiIiIjIoCiobZS4uFSpvl85TkREZOz7FME+Rw64pA/zv9bM7jazj5rZfvmRZpY2szcCDwH5k+pnDUG2mAHxc9nY8boeLiIi49C4y7gKlcflytQmIiLjiXPuIeDv4cO/mNl7zSwFhZvPrgaOCaf/wDkXPTl9KbCYoDzpDeGxOGaWMLP3AReF893unBuVG80Kwu489nz7cGitD/5OmDEy2xMREdnDmQ7VRUT2aKnRbsCeKi6Li86fi4jIeBPe+f3J8OG/nHNb+7IY8MbwP2bWSZCRbRqQDufxgZ875345tC3uu5zfATHZ2nRBXERExpOBZFztaZ7dJeNqHKcbzUREZPz5BLAX8FqCALduM+sAohFZP3bOXRpdyDmXM7N3AfcB84G7w+USQF042zPAh4e19X0w4kfgrfnTGjr2FxERGQnBJQYREdlTqRcYJXGHvL7TCXQRERl33gQcEA73tVzZYoISKDcAK4FOYHr4dxFwHnCcc+4HQ9rSfvK8jtjxvs5ri4jI+DIuM67Gcbo4LSIi44xzrh04Bfgs8CBBQPlkgnKj1wCvds6dWWXZdQSZ3M4ClhCc0s4CCwmO2U9yzu0a3mfQOzfC1Ufxw6ztOpcvIiIyIhIj3tmLiMjuRJnaRolzRnlom6fMLiIiMs445+6E/tUAcc7tBH49PC0aOs7PxY/XBXERERknxnPG1ThOkekiIjIOhWVF/0LfbzSLLtsK/Cj8v1urPNs+zBTUJiIiIiIiMuyUqW2UxFVj8XQCXUREZMzw83dnl49Xdy4iIuPHuM24GmXhJfCOhQtxmcwot0ZERET6I38I7rwR3rA/0huU8WLD0p1sXd002s0QERk7dL5dRGSPpkxtoyS+/Kh6ZRERkbHCeZUnsBN1m/AV1SYiIuPEeM64CuDKnlrzzbfQMGEqc77y5VFqkYiIiPTbaFUkU6Y2GQDnHP/8/SIAvnTBG0a5NSIiIiIiuz9lahslcQFsKj8qIiIydvgx5UdrZjyKunMREZGxyRl4zc2j3QwRERHph+E+BI+ruBJOGOYty3jUurNrtJsgIjLmmButCHaRwfMzHtmGztFuhsiYpqC2URJ3yNudU8pyERGRscK5yqA2cDjlQxcRERkTyjO1AVgyOQotERERkQEb7uvc1Q7xR7zeqYwH7c0qdS8i0l9mCmqTsWvn5UvZds5T1W+UEJFeqfzoKHEOvnj8BDpTxY64M6sDYRERkbGirbMDaoqPt9UGfbqqj4qIiIwNPkEAm4VXqx0OUgpqExERGUuG/RC8alCbyo9K/3W1BUFtiaQCNERE+kq/mDKWda9qCgY8Byl9mkUGQpnaRomP8cTsFIunF0+Yt2eyo9giERER6Y9HVm4pefz/Tp4EuNgS4yIiIrL78ctPiSTAkrr3T0REZKw6+bDZw7DWKsf4vm5Ql/7rbAuuAdVO1D6niEif6XS7jGVhHJvL6YYIkYFSUNtoibmTqyujHzMREZGxIt3UXPK4O2lgDsW0iYiIjA1e2SkRZ4YpU5uIiMiY4iIlydLJYbjcoUxtMoS6wqC2mgkKahMR6StTrjYZy8J9Vb8rN8oNERm7FNQ2SvyY2mSdGd3dJSIiMlYcs31LzFiHU1SbiIjImJDP1JYvP4oBSQW1iYiIjCX5I3A/kRjZ43EFtckAdHcGF7QTwxGAKSIyTu2/bgZ+twKCZIwKu/z6nz85uu0QGcO05zxaYg6wO5WpTUREZMzIVbnoHRO3LiIiIruh8vKjzsBS6VFqjYiIiAxImLzFTyaGpzpZ1UxtukFd+s/3XPhX14JEROJc+vylHH3p0SX97+FL96bpptWj1ygZdrmMxy3nPsPOzW2j3ZQhZ6ZMgyKDpaC2UeJijoY7MooyFxERGSty6bjdKBfbx4uIiMjux6csQD2Byo+KiIiMMdEj8OG5yazKSpWpTQYgH8zmdEekiEisPz37JwASZSEMuebMaDRHRsjWNc1sWr6Lh65bNdpNGXoKahMZNAW1jRLnV97J1ZXVgbCIiMhYkY276G0OX925iIjImFCeqU3lR0VERMYeF71O6A39Be+qFU1HstSpjBvFTG36/IiIxJlcMxmApCvLrO58Ft11Ow9ddQmZzo7RaJqMiHHYPyqmTWTQUqPdgD1WzG9yt4LaRERExoxcbCYXh68T2yIiImOCV5apzRlYUqdJRERExqpUrnvkNhZz07pIb/xccA3IU1CbiEisKekpbGd7Raa21h07uPu+PwLg+z6v+8inRqN5MkwKcV/jsXtMKKpNZLCUqW2UuJj05FlPQW0iIiJjRS4VX35URERExoaKTG0JsLSC2kRERMaS6FF4Kts1vBsoGa9z+dJ/xUxt+vyIiMSplqnNy+UKw35kWMaX8ZgvwBSNIzJo+hqNEhfzq5zzx+EvtYiIyDiVS8bsRpkytYmIiIwVfpipzcKr1c7Q2UYREZExxidbGE74w3CRu9oxvoLaZADyGdqcMrWJiMSanM4HtZVmVo/mujJlvhp3zHa/99Q5j5aW5wa/Hu0yigyaztaOEue2VozzFNQmIiIyZsQFtRk+6s5FRETGhopMbYbONoqIiIw5xb7b/BHsx53Kj0r/FTO16eSRiPTMzGaZ2SfN7AozW2pm7WbWbWabzOxmM3tPH9YxxczONLPFZtZmZs1m9qSZfcvMakbiefRXKhFkT09QPcjJEsmq02SMGkRM2+bNV9PS8hxr1v6e7u5tQ9aktWvP48mn3tNjYNtTze1cs3VnzyvK6TyTyGCprsYocS5bMU5BbSIiImOHp0xtIiIiY1p5UJszcCN5MVxEREQGzeUzrmLgDUemtmrjtc8g/ZcvO6qgNhHpg3pKr+N3AVlgXvj/3WZ2O/CfzrmO8oXN7EDgfmB+OKoDqAVOCP9/2Mze6JzbNVxPYDDKM7VF7Y5ZvUaL7/s0NjYye/bs0W7KkIirdFd9Xo/7Hzga3+8ujNu16zGOf9lVsfN3dKylrm5/Eon48JjGxgU88+zHOPk1T1BTM4vWtqUAtLQs5smn3sPLXno1M2acWLLMO59eBcAH95lVsb7udc3suGDwmd4GYvXq1VxxxRV85zvfYeLEiaPSBpGhpExto8S5yg5XgboiIiJjRyadjhnrqlYmERERkd2LF54SyZcftQQo5aqIiMgYEznNnvCHIXtatYP84diWjHt+uK/p+65fF+5FZI+UAp4Avggc4pyb4JybDBwE/DWc5+3An8sXNLMU8E+CgLatwJudc5OAicAHgVbgpcAVw/wcBuzwzoPKxhQ7fAW1Fd17772cd955NDY2jnZTBmUgb2ku11oS0AbgeRXxnQB0dW3l0cfexOoXfl51fRs2Bl+rlpZFQZvCz9yKlf8LwKbN/fu6tD1aWbVvpDz88MMA1NfXj1obJOB352h9YCOuH+cbnedouX8jfkbHG3kKahstMZ9bZWoTEREZO9omzogZq5OSIiIiY0VcpjaUqU1ERGRMcZET7cNefjR6vK9jfxkAP5LZoD8XN0Vkj/QG59wrnHPnO+fW5Ec659Y55z5DMZjtI2a2f9myHweODoff65y7O1zWd85dC3wunHaqmb1xGJ/DgEz06vjh5tOrTlf50aL169cD0NraOsotGXme3xUzNn5fMJsNEhLW199SdX1BLGiQAQ4gky0tK5qwuCQH/aNrR3ue5tvX0Xz7Ojqf76VMbUTH09touWMdrfduGMaWjS0KahstsUFtI98MERERGRgv7vYhc0rwIiIiMkb4lJ0IN1RKTEREZAxxzuFHLl4OR1BbybXHaHY27TPIAETLjjZsahvFlojI7s45d18vs/w1MnxC2bSPh3/vc849GrPsNcDacPhjA2jesKpxlcFDnc3NhWFLKFNbXj5r3Z4WLPWVe77CJc9VJCmsXjY+zLqWzTbS0bGuyhxB2IxzPpnMTpqbny6dnuhnUFvcx1TlxwFwWY+2x7buEQH+fmcuGMj5eG0Z2p+s7/X76sIMbX6XMrXlKahttMR8VnN7WIcjIiIyVvm+w0vE9dv+HncAKSIiMlaVZ2ojoYwZIiIiY4oDSoLacsO7vej6nS4ySf9Fg9r+/ZfnR7ElIjIORNNUFe7YMrOJwKvDh7fHLeiCE9h3hA/fMiytGwSLiwaKjBoz5UczHeBlR7UJflduRK9XeFmf3ABKJhbuS+hjU+/fdD83r7quYnxr2/N4XmflApHPTFfXlpJJnteJ72fBgq+Rczmy2aaKVSTCTG55LuYGh7YnttJ47YpgkzHtdrmRuSliMN+R+rN/ypY/XwRAyx3/ZuPnPj9UzSpovnsDTTevpvP5hkGvqzXnjY1rcgYtd61n1w2r6F7d1PO8+cDdsfC8Rkiq91nAzNb0PlefOOfcIUO0rjEt7jy574+RTlhERMYU9eND7/Yl9fixtwYoU5uIiAw99eXDwyvL1NZRk1L5URERGXLqx4eP7xwZ/3lgHomER3I4gtpKSo4qU5sMjhcJavNVukdkzNhN+/LXR4YXR4aPoJjUZkkPy+en7W1mM51zjUPUrsGLOb8eDXSzxBjJ2fPTfWDfl8HpvSXdG7ieMrV5rRm2nv04U982n6mvL69QOzyuPutxmnd08qUL3tCv5fI3GPYnhqfG4mdubX2e6dOD5IUNDQ10dHQwc2bk82Oln5/7H3gJM6afRLpmVtgGj7iQNEuUhtX4fmXAYtONqwGY+YEXlwTS5Y1UUNtg7Lr8cgCmfuKTbP7614dlGy7MXuZ3DG7fvb47y3GPPM//HLwPXz5wLplMIy0tzzJ7ds+fv28/8G0WbF7AIx96ZFDbj7NqWyvtGY/j9p9eMS0xIcj21722mbrDZgz5tsezPgW1AfN7me6IDzgtn6bLvKFsRzvUlY7zqtR5FhERGaT5vUxXP95P7d05vLhXzNzYuCtERETGmvm9TFdfPgCu7CXbMX0SzlfWFRERGXLze5mufnygfOjaa0r4wJGKubg4aCXlR6OZ2nQuX/rP93ymzq6jpaGLqbMmjHZzRKTv5vcyfUT7cjObDnwvfPiQc25FZPK+keHNPawmOm1fYLcJaktUfSkD5UFJu7UtT/c+zyD0GNTWkgGgc9GOiqA2zzkSDH3Wu+YdxSxpLrxpsC9BiAPJml9bZbXRMqHnnXceAGec8V+ROSoX3NX0GNOmBYFwrkq8RsJqAHjhhXOYPOVIZs08ud9t7mv5UeccX12+gY/tO5uXT5vU7834BD82g7lW1RnJuOecG/BnxTmH73ySiWRhuJCJbJDlWLd0BZ/xW3c08+UD57Louc/S0vIsr3vts6RSU6oud8e6O6pOi/LD/f1EP35z3vzbBwFY9/N3BCMi70FiQpgNMFf5vF3Op/HaFUx90wGFnsI5x4033sgJJ5zAAQcc0Oc2jEd9DWr7ZJXxM4D/BaYDjwL3ApvCafOANwCvAnYBZwFNA2znuJPLdFWMU2YXEREZJurHh5qBF7Mfu1/rfrrKICIiw0F9+TDwwxPlJcFtOjAXEZGhp358mPjO4QoX2IzkEAW1Vb0AGA1+VyC8DIDvOWbvN4U5B0yhcUv7aDdHRPput+nLLYjouhzYh6AE6ZfLZolGcnT0sKrotNjoDzM7HTgdGNGACosJOmIQmdo6nn4GnM/E448fZMvGmDBwKC5gbN79i/iPOdO56CXzh2XTzjnO+9QHmDR9Bp8698Je5/cLbez7OZlqmdrKy4QCdK9dWxiuFhTZ3PxU0AKXiw3gsnC969afD8DJr3m8MC026CsmBsz1MYirzfO5vn4X/9rRzAuvPaZPy+TtyGT53gHH8prufi1WoeTp+D4ki9UOdu7cSS6XY+7cub2u54plV/DLJ3/Jwx98mAsWXcAVy67gwZk3A31/Pao3Mvjjws9NR0fwPjs3NPvpr7jyFew/dX9ufNeNPc63cH0j82dNYtbk2l7bGqh83pnNbXQubqBzcbEka8bL8dzzz7F8+XK+//3v97P1A9fY1ciGlg0ct9dxI7bN3vQpqM05d2n5ODObBDxJ8Kq/zTl3Z8yi/2tmbwKuBT4LvGIQbR1XEjFRvrq3S0REhoP68aGXMCOXqDwqeVHT4fjK1CYiIkNMffnwcOGJcj/8a+aUdUVERIac+vHh03bvBib4NYXHSZcZmhW7KsO+yo/K4PieI5E0aiel6WxrGu3miEgf7WZ9+e+Ad4bDX3LOPTcE64zlnLsQuBDghBNOGJGT3g5H0lUGHUXPxPc3Y9T6D30IgCOWLxtM04bEske2kEonOezlvQcD9UVPmdosGb5OVW7e++eOpiFpQ5zujhyZzk4ynZ09ztfRkuGxW17ggCNn9XsbNVU+BhYT1Lbp61+DH/Rtva7KTRKV5UeL+50+kKR3ro+lx/PfgMwAbrzc3BW0f8Xe/Q9EdZnic+puz7LsxR/msNV/x3keFglq+8Mf/gDAmWee2es6b1wVBITt6NjBFcuuCLaTCMvNDrIUuxVuVi03ND9XXV4Xq3at6nW+957/KCftt42z374LOLzKXEYkCg+AdQ3t/G3BWn70H0eRqK38BG1t2xIsGX7PNzZ28OcHX+DM/ziKVHJoM1Y639F86xomnbQPH3n4I9Q3b+Wp/3oSq00OeUbHgRjMs/0e8GLgC1U6agCcc3cDXwCOBL47iO2NKy5bWSN4sMGoIiIi/aB+fBASBl5MUBs4JXgREZGRor58EIITvkFfnsvf72fge8q6IiIiI0L9+BBof3Az3anIBSBXWR1lQFyVByo/KoPkez6JpDFhcpqu9mwkM43sqdoybXzvoe/R1NU02k2R/hvxvtzMzqGYme0bzrm/xczWGhme2MPqotNaq841wjznkRziTG27k3svW86df31+yNbXY7BJWaa2Cx98gfnfvY2WzDCUay/TtL2nJIFFC25YxbIFW1m9cBtQUqmxR5Mzk5no4nM3LV/xv9xz7yHU1/+Dk197OTW17TS/v7jf1lv5Wt/vZteuxyvGm6VLHt+5s5hx1eul4ZYOt1ml39+1axdNTU3F9YV/swNIoGCFuCnrd/lRr62tMLzs/s1s3edVbJr3eujDubLt69bQFVm+nMORtGC/3Q+D2oYqOKa7u5szzzyz8Hz9IcrU1qsn/wpnTmMyHXz2yLNZt/5PVATU5R9aMfg0mws+j1+5+hkue3Q9S7e0FEuyhvxkJzsaFgaLhm/q1655hise28CiTc1D/lRyjV20PbKFnZcvZWPrRt7RdDJbznwU11kZ0zQaBvOr/59ABrihD/PeAHSHywgw7cEFFeN0GCwiIiNI/fggJBOGX2Uvqr8HCiIiIgOkvnwQfOcXyo/mCE5MmgUXGkVEREaA+vEh8q8jjy0Mb629f2hWGj2uL8napkxtMnC5jEdHc4a6SWkmTEmDg+6O4Q8skN3btSuu5dY1t/K35+NikwZuw/M7Wb9kJ7f96TmWPbJ1SNctBSPal5vZL4FvhQ/PcM6dW2XWLZHheT2sMjptS9W5RpjneyRiMrVFJcZwUNtw6fGaRBg4dMEDawDY2j5EmW1jTJ4RlF9ct6ihlzkDhfKTfbyk8siWR7hl9S28dfNbObbpyNh58mVEN22+EoD95i0le1h0v634+Wnc9WjF8o2NC1i+ojKtW8LSrFv/58LjG3YUb6bIxbU/EnCYD2pzsTPC7373O84999zC48FUA8o/Owf4fv/2V/3WYnxrvg3ODNeHoLbL//urXPd/1UtkOhyJMKDQt6HK1Bbo7AzeCy9c34rlQxc42qPHglK0c21XYVTCqj+nrkzwOt6/YjsAuTDI0YyKgMfNx/2B5PEXYuYVgtry86diE24MTv7jmtvRyUFd84q/w8OwrYEYzK/+AUCn60NR2nCernAZAdLbd1aMy+hODBERGTnqxwfBzPBi9qLqrKtw55OIiMgwU18+CD4+Ljz9lQ2D2jCH7+0edyCKiMi4p358iDmMFJDxhuBCbZWYNmVqk75qa1tBc/OzJeO2b2gll/XZ74iZ1E0O9j+72hTUNtq+cd83OOGKE0Zt+17YDaRiyuUNxj//sIhbz1vEuucauPey4Sm5uKPhHtau/cOwrHuMGLG+3Mx+BXw7fPgd59yve5h9GcU8Ki/pYb78tHrnXONA2jXUvJYWpjR0VCk/GgkQGsVSeF5TU683tTvn09rat+/dzs1thaydzd39y77U3N3Mo1sfDbcZ06Z8UFK4/nxsSkt2cFmsdt28mtU/fZCbbn4Fjz760ZJp6bCEopfreT9px8ZWbjxnIaue2t6vbX/urs/xk0d+QF1dK4lEz9vIfzVzudryKUDw2j/zzEcqluvoXBu/QjNeeOGXxYeRr355prYVj9eXBBTHZWpr3NpOrsp7MZgEZoVXxQyvSjDaypUrOfPMM2mLZFZr7siydXtTcT3RNuR6Plfm+8F2dqxbU3WerJ8tZGrzzIvZSKmWnMeSLVvpbG2pOk/+dS8kQwt/G2677Z/88Y9/7LHNADl/kOcAE8HzSUSOGJJW9ppHPhu58HvR0NodTioGtZVfV+ycviqc5sCMT178BFuaguC95DAEmrnIh+73a79b/B0eB0Ft7cA0MzustxnN7EXANKBvuSb3AC6msHLH9oUj3xAREdlTqR8fBAO8mH25OjIkMkOf+ldERCSG+vJB8J2PC0+JFMqPQtUTfiIiIkNM/fgQ8MvSeqTNsa1926DX66plavOVqU365vEnTuWphe8tGZftDj4/EyanSdemSsYNh/ambv781fvZsXG3qSq4W7p7w910e90DW3jzQsh2Dmr7+QvqiV7K4e2OnnvudNasPXe0mzGaRqQvD0uOnhE+/I5z7lc9ze+c6wDy5cLeVmWdBrw1fFi1dOpIW/e+9/PZs54mScxF9Mi5+PbcyOwSLVq0iC1biknsuletYuVJr6Tp73/vcbn1Gy7iiSffSfOUnoNVd25p45r/e4Inb13Lk1sf4yf/OpF71t3e5/atbV6LC3dUtjXHlGDP78MUgtqCF3FXNvjdqR1gsEr7Y1vZ2raDqVMb6Oh8pGRarj34TexpN2ntcw1cd/aTbF1deR2lLwnKvja3i5efeDOW6LkP9cPf9pxX+j74vkfzjg6u+b8nYpfr7NwQOz6bLY39vKOpOFwe1LbwpudKHls6+EznM5NlunJc/r3z+dcfH+SR66+sbHtfU9fFtdMvBnpVy9T22GOPAVBfX18Y94Zf388n/ha8Ji0TJ3HLpGyhFb1lastlKm8qqX9hFUsfvLfwOONlipnawtC7apnrHmtq40UPLeZNK7bx5y98vPp2C6976XrMfHbs2NFjmyEItOsr5/s8esPVpSVWw+eTiNRjTFbL1GbRANOY716VAD8zR3fW574VO2hoCz7TwxLUFglETZEkEZ4ztXEQ1LaAoAs538zKQ1wLzKwGyBeQray5uaeK+QD4oxhZLiIiexz144OQqJKpzTeHH3fQLSIiMvTUlw9CtPxotqT8qILaRERkRKgfHwLdlPbbKYOt7f0rs7dhyXNsWLKohzkiF5iiQW2+9hmkf7xMcLEwmU6QSgUnlbzs8AVHrn9+J7mMz3P3bhy2bezRWrbCRW+Af35tUKvJB7UlE8N7PrFaNiAZlGHvy8OAtmjJ0R4D2iIuDf+eYmaviJn+PuDgcPiy/rRpOGXWrwcg4eKulxfHPVb/+Ii056abbuLCCy8sPO5+IchC1f7Qwz0u19q6BICuup7DMDqag0CgrS80s37j5bxtWo76TRf3uMytv/slt/2+8mPQ2hWTqTYf8OM7dl58Cb+8+SwAmjLB787EPpZxbW9/gXvuPYSOjvgMZn74O+Z7Pq2tLtxk9aCsXVvbK5vaw/azmzez7Igj6Vq+HIB90mFgUC9BbZ6fD/Qr/Tx1r1rOzk2VbSi0pUryxUymWIVvB3NKppXHZlnb5tLHYaY2ryXDc/fcwR8//Z/kOu9n1aO/5nSbxQWvO41N02dH2lC1eb3K5IPazGKD2rK+oymZrhi/sz1DIoxG/N0HP8VNUzzW7B3M53LBa5LZGL9PERfUduX3v8Htf/xN4XG3113I1LarIyzXWSWQ67RnVheGvWz1wLNsPlNbYTXBe91bFr+8ahmeO7IdNHSWltBd++xCHrnuSu69pFiCNh/UNpligHtlprbIYD6oLf84nOb5rocvgcMHzjj+PN7/opuC5cOYoqZsrhCkGueRFxp40Q9up7kP5e4f31hainc8lR/9OUEGw1OAZ83sk2Y238zS4f/5ZvZJ4BngDQRvxc8G3+TxwSUrX3o3Bu/EEBGRMUv9+CAkjNigNuj5gE1ERGQIqS8fhCBTW3BiJqfyoyIiMvLUjw+BpnTpRaM5U3y6vJhMJT24/v++z/X/94PSkVUztan8qPSuo2Nd7Ph8UFEqnSAZXtzO9VKebTCatgWZjLwqWVDGulXtXdR3D1351t7KCVb4W5jkamtPQbG988PfknSiMsBgKDVv73tGOecca9b+ga6uLb3PTDGgZQ80rH25mf2SYkDbN3spOVruUmAxQYTHDWb2xnCdCTN7H3BRON/tzrl7+rHeERGXqS0aVlGbqhvU+p1zbPmf/6FjYd8qqGW3hSUy88lpet0HCObr7VclnwHJ+Q5cEFyToOdArRWPPMjyBQ8UHrsetpJvpvMc23/xC+a2Bpmr6huDjGOpHoJVnPPZsPFicrl26uuDQJpt2//F5Vsa2FljMKEY4LVq1U8AeOTGFyLb7qFdPf3exkxrve9+cI6m664vGZ+olhEr5FfLwmnQ2ti//UWAbHZXsZllITaec2zf8W+a9w0CHhNl74zVBJ/pxquWc9eF5+FHynk2zNobgIUHHl5cXw/va0vDdpbcd1f1dkZew7igtv9euZGf7nsEmWRlJsFEuGzbxInB8vmPiJej9e67eeHNb2HJDTdWLJfL9J7xNONlSISBlP9afRswgL63fLtl5UcLrG/rrZap7X3/fB+nXHdKybh8cF22K9KfhrE9N9T+uDAqWRZsWWyJFb4XyfxPSTg1m/VofXBTbFvMfJyDI2at5K3z7ytZ7vCHl3DEw0uqPr/z7l1NxvN5fkvv1aWuWXJNYdjHJ5n/jO8eMW0DD2pzzj0GnA54wIuBvwAvENQE7wqH/wIcEc7zBefcyIROjwEuJitb3DgREZHhoH58cMwML+agz1H15hIREZEhpb58cDznFU5CZgtBbSo/KiIiI0P9+NBoTZYegL/y6A3Ur6mvMnclL1clEMNVGS4JatM+g8R79LE3xo7PhVnZUjXJQlDbcGZqe+bODcO+jdF08hPLOe6R54dsff0NiKUpyChFsmZQ2/XC35J89prh0ryjeBG+qy1Lpqt6IFpn5zrWrj2X5xZ/vk/r9rxixqPOzviL8uPRcPblZnYA8O3woQ/8t5nV9/D/jOjyzrkc8C5gHTAPuNvM2glKpl4HTCUItvvwgF+AYZTw48+759UMMgg0u349zX+/gS3f/V6f5u985ulgIB+I0ksgjhWiQHq+7p9PlOacwxWC2RJc99MnWftcQ9Xl8lo845YTv8DyuQdgZWE9flcO8oHTZRcsFj7yQLil6hoa7mXVqp/wxBPvLIzbnKnh2ys28enjMmRO/F1h/I4d93P1WY+z9OFiIGxJUNvjF8JVHyhOi3v5enpJC697aX/We6a2ILjbyoPf0km62vsfFL1z5/2RR6UN9pxj8eIvUv+Sv9C8zwISZdMzfShV7Ucy5/V0jemq/zmDf/7lT7R0xvdbX1oa9E+dNbWFoLb6Nc1cfdbjZJsb+XdDEOCUi8kQms/Ulq8uaA5aJtTS1tZGx6Ln8M34++LnKpaLy9RWLuNlCn1dKh+4OsiLafm4/WjgGPQc8Bj9/ma9+M/Bhtb4ErQFl70bFl1bCGqLKt+2n/+sORdkZANSYTvNc6QcpJfuonNx/HfezFW8TM1Zj0yV0rJRhafahxCkpF98Lh5+kKnNgmuhu4NBpQZzzv0NOAm4g+DzYmX/XTjtJOfcRdXWs0eKSenp9zHNp4iIyFBQPz5wyYSRjem3naESJCIiMmLUlw+c7xcztUXLjyqoTURERor68cHzYq7QNG1t6vPyHS1V5o1eOSrJ2hbZT1CmNonhqgVKAtmuMHgplSA1AkFted4wZoMbT9qz1UvR9ShVtepkn+TLjyb6WcnJOYfvZ9m48VKaW3rPFpfLFH+//nrGQ1z+g0d7mDtcJtfap7bkg9oaGu7lkUdfx46G3S7x17AZxr48UTY8t5f/k2Patg44BjgLWBK2JQssBM4I27SrfLndQdqP+z4U++PaQQaTdi1bBkDNAQf0aX6XP09QyNRWOv3yLQ38cm2k/Ln1LcORhdcXfM9F6hAm2LGhlbv/1nvQ7rZMsIHn9z2oIlJsy5mPsuMvi4PmlkXE5G/Wtx4a6IelOzu7NhTKbna7IBCpvSYF6WJAVTbj0bilnWy3F1k+ss3bvw0r7yg+jolj6jFQsPC6l87TW1Bb/jmUBxn1lN1uoLpzHYXh+qMvosYSzKspvr6bVy3tdR1epB/oqe9u39XI7z79v7zoseWFcS0tz9Hc/CwADWE5yq50LU89/DDd69bx4DUradzSTuMv3oJ1NlVd9/HbVwDF6oINUxN8/Wsf5HP3LeCatlbueeMb6UqlWT1nXslyPQW1rW4KSok+uuXRQl+XdPmgttJ5vZZuOpeUBnf19G7l8qVW8/OGgV4VgYzRZVxxX61aprZerbkfbjq9+NmMSFtxnV5rhsy6FvKN9L0wU1s4/V2rfb7cXIeLDTQP5jXzS16DJD7vXr2e/1q0pmrzMps20/bAA/jO4U9K8Xx375n0Un4xyNG3MFPbblJ6FKAyr2A/OeeeBk41s2nAy4C9wknbgaedc73ns9sDuWTlh2DDvINp9zwmJYf3jgwREZE89eMDkzDIxQW1hf9ERERGivrygfFcDj9fftTSwblRc+RUflREREaQ+vHBcZELVoUj8X5ce3FeP4N9ojexDbJcklRq3tHBlJl1JJJj9+b/tgceiP0MvvDMdh6+fhUAqZoEyVRYfnQMBrU1ZXN4DmbVDPry4m6lM9sJEwawYHJwQW35TG1+PwNlt269gWXL/7vw+I1veKGHuSs/az1lKbIwk47fx4v9+eC35pZnAWhtXcqc2fEZC8ej4ejLw4C0QUcTOOdagR+F/8eMGi/mOnmk201ZGlq2QqYdZh/a7/V7zUGQSXLatL4t4OeDS4rBVbkdO9j01a+x3+9/x7dXbAbg2/P3xswKwWK9lx8NV+e7yNxh0LPX+35GOgw48ROJiixmAC4fZFYWrO+HG87Hq2zZcj2tbUt58YsiH5NIgJXvBwEx3S7MglURXBaTWa8f5UctmSkE+8TtXmU2ziS178vAd6SzxRkSyR4CyUlxjv9tPsgVJBJlQW1ebgi+XaUryESC2gCOn1T6ucy50t/TvY5rwPnGtsWzC+P8SICU19s+ajhvZnMbNfMm8+RT7wEq+4Jlmzfw0AffR+cp5wKQTnRC+NvuDDKrV8OhxbZ+dPmdJW3ZMT14jTfOmMuureth9izuOvLlbJ6xF3s9voubb72VN7/97SXlR1vu24Clip+fOa0HcOLGU7kx9xdmTp1J0nOkwwCqrlW72HnFUmZ++AjMjB0XLSa3oxPeOqX4usRklMvL5PfNww9OtquL9IQgu1m51kwrX77ry5zceDIzumewq3YXj2x5hHOfPpdzXndO34PLG9dAPq7WEuRcDUkyQRvMeLFt4LzUn3Bdr6F7TfF1Oau9ibk1Wd4HXH34BDZfez213VtI1x5d+PzHMXOFm3IBJlqGdmBBU1vVZdb8x3/gOjtxX/8bmdfM5YfbdvDZI+dVnR/Kgtoimdp2FwM+OjCzv4X/DwJwzjU75+5zzl0b/r9PB93VuZhXfvmhx/Ct5RtHvjEiIrLHUT8+OGbEZ2rDYg8gRUREhpr68sHxnUf07IwXJv/3FdQmIiIjQP340CitTpbPOtL3bEt+lQytJRdUq5UfVZb2IZXLeFzxw8e47U+LR7spg+Ky8fuSqxduLwyn0oli+dFhyqIWDRjYtHxXr6Xy+uPwh5dw1IIlQ7a+3UVHWUBCnyUHVwbRC39L/vTsn/q13PYdd/Q+E8UkMrmMj+877l2+rddlXBho5/pYZrmh4b6S+RPDXEp1d6G+fPjUeL1EUjgHvzkczjt+QOv3u8JSkKk+flb98kxtjl3XXkfnM8+w45prC7Nt6c6WzteHgBCHz9LuO8g0hcEvLsELe6dpS1T+bnvtWebWzS88Tofb8c1oqN9SMX9kIwUJikFt+eYtW/5dNm26rGyhYuPz3+32MOjFKvqUyrbGXSLp7u5m5cqVJeOm7PckL37vl3DJdVWbn9s1iQknfp6m667jynOKv0uJRPXzNxs5kCV2LH/lcySs9LesJbMY37ZXWbJvvLIQmw2b15U87pqyju5JxffEc6Vt3fcVO5j3yu3kUsU+xC8JJOxbv+0ypc+tor934CeMjpYgk5rvkpFJht8Vn8HLhZ8tF752LvJZbqsNIsBvPu5kPj9pPw55cDH/aokEtf17Pc23rS08PmX1B5jTPYt3b3w3U7qncMlvPN6wOFih19RN55KdhQDM3M7Kkqo9VTr8xwu35Z9myd98prZFixbxk5/8hFwux/0b72dZ/TI2vbCJ1295PQBnP342d62/i9ZM3zKTArC9mHUv40/gz9uu5cn29xe+MWc8fjVT/96Kv/IusluKxyWXdLfzi6nB5+CpvWv4zV6Hkeu4K3iOsfuD4bGNlabRmGS9l3p1ncFvnN+P/b/STG2OxG6WqW0wt7x8DPgQQT1u6SdX5UOwvD2+/rGIiMgQUz8+CAZkY07QTKlfi9/fO71FREQGRn35IPjOK2RqA8iQBoOcLlCLiMjIUD8+BKLXaTwLskYdNKvvgSG+X+X4PbLikktB0f0Er/cyPnsy3/O5+bfPsGVVU5/mz2eR2vD8zmFs1UiIv3iYjGSfSyT7X3502SNbadvV989c+cXwXEbnqnqzsXWACSci5UedczRu2dyvxfOZ2rq8rn5la6ut3av3mYCJ04L25TIef1uwlp9f+HSP86949GEevuXHADjX8w0/yeQkAFrbni+Z3/aQoDbUlw+b2ExtEf25qTyzqfI76cJAHkuWZZx87HxYt6Bk1L77LqMh+VTwIBLUZmFA3Dlz5xfmbStcF+hbpjbnOZzlcHhktoflPl0dV71uCte9qqKiLA1/Xczr9/lAEGwSaY6XSPDC0t7LEAMknI+fLz/aQ7yKRUJIfBcE0axZHWSGKg9qi4ubiQvKuummm7jqqqto7yoGEE2eF7TbateE66r+qi3af05Q+jQ0e/amHtofvBeOBFaWqW1z5410TPh01WXLtWYmVYzzKP2M3nXvv0ser3/lmax79feL87v4zJeZVLGUbjR4K9eHTH1AxYu/dtGO0nYmUyR9v5AJ7LHEkYW2+5ZgY9Mu7rrrrorVemFbMjVh6czI+bN8pr6O2mJ604e7ejiX5hyZ2kYAJnRMoDZX+R33O3LlmylYdugxVVe9YOvjANSn65g4dWfhS5cParv99tvJ5XJ0hkFe+bKnCRJkag+nbfoHwiY6fnf3Ku5b3r9gx46NQWnVFZ2nFLad6A627VmabH3fbrbJZ+a7Yb80/37dHNYnduCXlB8tvs+Tewlqa4m8n30NaXO5HKdte33hsY9P0iUGF0k2xAbTlO1AhxvKWzz2IE4lRkVEZHSpHx+EBJCzJImyOxYntjSQ66ye9ldERGQIqS8fBN/3cZFTIjnSYA5PmdpERGRkqB8fAnGJXMz6fqHbVQtmL8nUFnkQzdTW2nu2oz1Z265uNq/YxV0XP9+n+XsquzSmVPlKl1e0ymdq60uwWXdnjnsvW8Y///Bsn5tR/nrmsiN340ZDZwNnP3Y22T6WrhyI/mQe6c3ciXMBeHzr43RkB5CtLVkMSFh4281c/I3PsW3N6j4vnov8rnj9uMEmnZ7Rp/kOOyEIfstlfZ7f0sK7O4pBeL+7exWPP/drHnjwpYVxt577c5JzHwLAeV1w5jTYsaIw3TnH/RvvJ+tlSaWC8nCZ7h3htHw2qz3m+qf68mGS9os/mpfMuQWgJKgjl+v7d2XDJz9ZMa6Qqa38rbvju3DJqSWjDjn0KdZNvIqGy5bSfGe6uFxYEvG+qbMK8z7RHAZ9hZE5vpvCpq5b6VgUHygTfHTyOzNBW3yCbTRMDdafzXSzcWmQxTRbH/5G5UtPZoLfj3yGr1wueNxT6c+k70cytcVHtTnnaNz1cOHxjh1BScodTcH6ExVBhZXbi7txYOfOnbTWTmA90fMuwbLNDfFJf6Jfr80zp7J4/74F9OafmY+RiNs3tL4nGfr+vT+rGOeXBbVtnDGXHNV/+3J+jk+fOIGT31garPiij20oDHuRKMOS9/CFewuDHc1NJcuXf4Q7WltKHq+ddxCJyD7BU8nD6SLoB5wZj69bx4IFCypW5sLPyLJ951c8l8pMfdDVXl8xrjh/sVJCZy747lmiPKgtS+M1yyFmf/Dfr39P7Hqdc3TUFQPeph63ipqJwb5Hvvxo/vPjnMPhgpKaoea5P6Bz6juBIMD8t3ev5JOXPFn1eeQ1TJrFw8tewrJr9sVzwfc1EflM5zdxzbUNdK3YBcCSaZHzjzFfuwfqrwbgZ0fV8YO6Lu6qeQ4Xfm4nTGzhTa++qDDvJCpvcsg1NtK5JNjn3vyVr2I1k0lMP7B6Gdszp8H1nwDA7+5m+UuOZt/MnMJk3/wgeHb3SdQ2qKC2J4BpZtZzAVaJ5fqa0lRERGR4qB8fhAQ+OUtSQ/ldEbvRXp6IiIx36ssHwXceLtJvZ0lhBl6VMmQiIiJDTP34EBhsFEFfMrWVLhANauuhzJeQTAWXntoau/tU+nLnpnFyg2CV59rdUXrjRCFTWx8CM1x4gbelobMPm3c8/vjjtLWWvp59zQg3FP7v0f/jmhXX8NiWx4ZtG92Ri/1dLzQVhp3v2PGXxXQub+zzuvLZ0a5ZcQ2vuOoVZLwM//3gf3PDyhv6toLIhfmtq4Oyeru29j1bmxe5YTbXS2a0KNfHoMGZ+04ikTK8rEdrZ+l5zN/evZK2hj+Ry7XEfk/9fEbKFf8qjHts62N85d6v8J0Hvk13dxDE0NUdBPlu3Hhx8Dxy3azePk6+0z1TXz7UwuxQ0aC2O6c9yqb2lVgk4Cfbx+N25/vktlcGlOUztblc379zXUuDTKIdE+bQQR0WJq/xIucVvr0izByWDzJzs4NlninNngXQ3ZEluhti5INvis/9Rwv+l3t+/Gmu+/H3giyQ4fc0n0XtkYeDYLd8Vq1du4IAGnxHF1lyxLxOtcbDhx0btKs7x91LK4P0t2y5ls2br6oYnwnLLSfKfy8ceNkV+P5NxVGR/u33+3+Yp6ccgZ/JcOVJb+W/ZybYMiPJfS8pZvryc1X2FcqCnMoDqtqYzMV8lgw1tGwsZlQrzdQ2uPM8H2qrrRhXXn70vnmv4nr+q+o6PJdj0YwUnanS60f5ADMAS/lkMx4PXLWChk2RcpiPXVAYvOw7XyldcVkAo29NJY+fOPJEHj3uRKA0MDSYt7QtqUh/VF7yM7pkxfsPbGxvqBhXWNb5dE8IPmee7+GAp2fn2GXFfsJvz9LxbOX3JG/5ggcKw8233kbzrbfxZHM73RNPLIzPhQGhO5nF3fu+Gp/ivn6+j0u6yvicYzYfzKK7buRjyX9XTIvzg9PO5j8//0cAsi74DJeUuA038frcocG2gU+cVPxsRoPa5k9+CQfUGMmYkK177U08y0s56qj7S8ZPjMnUtu4DH2Tdf/5ncZ7XfY9Jr/8BFgmW717TBEBLV7j/8Hzwfe185pngb+SzlHBJki6BGyeZ2n4X/v3xUDRkT1MtNarC+UVEZISoHx+EJEbWkqTLg9rMqt/pLSIiMrTUlw9CzuVKyo/mwvKjbZm+360rIiIyCOrHh4Crcl9ZX8uS+dUuirtqw+F6p+wLLVv7tI09VfR656Zlu3qct3FLO//4/bPD26ARUi2ALxOW5Trlo4cDQQlSS1ih7GpPvFwwT9UL/hFbtmzh9ttv57Z/3VoyfiDlR3/1q19x++23l4zrS4a05kwzAHWpuj5tx/ez7NhxZ5+CH/MykUiQhosWF4ZdxqN7dRM7L1/a53WVZ5RrybTwr7X/4sxHz6y+0AO/LA4niqXwEmEQQLWA2S0rl/PrD7yzJOgtmqktOtwbzyvNKrf6hXNoa1tRMd+EKTWka5I8/e8NHLWwehk036/M/FIIgEikC+PyZVqbdxYv/nd11Ze8f/ct38CbfvMAje09l0gbB9SXDzFLBd+nGq8YvuBcUHqvtBxm337TtpxxBq678rOdz9TmssH33/M8Nm/uWzDqY684k7vtXYXyo37Zvkgu69HVns9aGHwvutqzrF9SWl77L998KMjGZfnvTvB3xa614bI+N66+ic1Lg/2NdZt+xYo3fiqYFJ7LuGy/o4P2h0F0bW1BkJDzHFfUPcjtNc8UtpdJBxnCOo4uZmPa1dpFx1c/QZbSMqxdXfGvRTKZjh3vgANe/yeO/OC/wMswqW0zuUw3zZOn0zppCj89+HROfdkFZLcUbwj461um8fBREwrnZbLtt+Pngukr27tYum0tO9ZtLgR255UHVN3E+7jb3sYDnIJXV8yCVggSxEgk4j8vmZq+BUDP8EvDaTqYwAbmV8y3if35C5/n01xRMc2vErTcHQlqc0nH0/dtZMmDm3ng+lXF8TUTg7/O0d5Utk9V1nV6fivlbnnDB8ikW/jJB2bx9P6HFReNBLXVN3eSjlQuyJeojZs3NlMbQRsTkUqF6UTw3PJZzE5+7eW8es52OidMYvHMLHfUPFvcXkfP/d9tv/9VYXjLGWfw7z9dyLueKc2K2sZktjOXc/geT84+jq3TZxf6Jm9LUOY26VcGtR2cPZ4Hn97MF3A8zNSqbXA4cmUliwtBbeQKX2UX3tiRCwPdmtKlr2U28nF62V7v4LPvmcHSmcdxZe1DJfNdnPgcv7L/qWhHsq7yACi7MeibXXhsk5g0h8yEHUyy4uel/m+Pc8+9h/D3B/8MwLVTJnP0pUfT1doEwI37pznhrVPoSkCtSwdZ7XqqUTzCBhzU5py7D/gG8HEzu87MXjZ0zRr/qu6e92OnVUREZKBGoh83s0+YmevD/zf1sI5DzOzPZrbWzLrMbIeZ/dvM3jvU7e0XVyVTm1H9rLqIiMgQ0jH54ASlB4qnRLKkSXk5dnTsERkFRERklI1WP25m340ej/cy7xQzO9PMFptZm5k1m9mTZvYtM6vpadmR4lU5y14e7FGNqxJ4UnKtLq786ITpkO09a9aeLBrUU54ZpFxH67gPfCGX8dj/yJkc+ep9C+OS6USfMqgVgtp6KCcH8Nxzz7ElDBjo7Aw+n3u//BJmHn57YR3VbNjwN55//psl49rb23n88cdLxp2zrnp5sbx8Cc90Ij74odzatb/jucVfoLHx4d5nDnVXeS1c/vWMTt+1Dv+PJ7JuxS/J5SqDujJeBnDU5Op495KvsuzhPgSs3nd2cXhisfRg/mJ+U/0WaK2Hx/9cstgLTwXZ6xbfdxcNnQ1csfSKkkC2D932IbJefAa2bXf/nO13/gSAezfcS0NHabbI9evP5/EngrKJ0c/K/kfMLJS7rckWx3vZdbxi1xPFx17+OChafi58PSOBe9s6gmw7k5LBfNlsDZChvnlZYZ7k2seYmWmktWv4StDuDnRMPvQsHfxu1HjFwJO6bsM5v6RUZtVMq2Va/nV77PjyTG333nsvF110EfXM7r2N+YEwuKW8JfdfuYK1zwZZq/Lfpm1rmrn1vEU8ckNpEI7vu0gfGfztDmurp2rawzYaiRqPXW3/hDA4y8oCTTLpGrKJJB0d4f5PWHJwW6K5ME/bpH1L2w8wIcnpP/gZn7BrS276syolhHNh8JxvVravBFPmhduuyWDOZ8eT/+DCj5zBBR/978gKKmMg8tnCnAMvswrn4LVPLOejT26l+4I1uLB8drN14CdTZNPxQUc50viR36p8Zn4fq1qavruuemawnvyEs7jQvlwx3pHgPnszXTahYlpXlX3TZoqlpHOk+PP9a5icgP1rIueraoJSz4vv31S5grIAs4wflB9N5Yq/v+v3ns59Lw22/8TBRxXGRzO1vfJn91ATLYedqF5xsLL8LMA0AJLp4iFC0sL3I/L6v3xOA88d9tqg6ZGl/V7KpOezETZu2cyaOdO49+WvqpinjSl8w/7EBjsIgHRdeyGo7bk/f5vMmpWxmdry697mvz1228nwsMf5Pv9+7btLpmXCoLak5ch/u1LzXwlA1oLXc3tdeVBb8XFH+BLdevChtCX61mfe/epXV4zLv5YPriwGnK89+dt88qhvFR6vm97CLbyHff1LaVo7gYumB9+l1rZGfODqg4PnubPWqHHpoPzoeMjUZmZrgK8DWeC9wJPhwe16M1tT5f8LQ9Tusa9aFHnDypFth4iI7JFGuB/3gW09/K+8XSpo46nAc8DpwPxwvpnAW4C/m9nfrPwIboQ435GzFGlKdzRTEzx8p0xtIiIy/Ia7Lx/XwekEpR9cWaa2JK5fGSJEREQGajTOrZvZi4Ef9XHeAwmOx38EvITgKk0tcAJwDvCYmc2ovoaRUX5PWb4UlOdVz0YUVT1TWy/lR5Np0LF/j1wkqCaVrn5hNJg+/FfMWu64g2WHH0Guse9lKQekvCJb+FnKdnuka0pfh1QqPqgt2+1x4RlX8exD94KXxbvzrD5t+sYbb+S2224DHIlEkH14+kEL2OuYG3vN1LZq9dnUb7sldlpzczP/+Mc/yOVy3LitmPHjjde9kW8/8O2K/ef2bPD9K8+AVk1H54Zg/mzPGf2iumICWlof3MTWs8MgvGiTnr6Mrcl1vLD5z2zY8JeK5V43qZUf79vFkTtewT6tB7PkH+vZu+WgPreFSMWGfFDbo3+/mrU/Pglu/w40F4MQJs0IAuCad27njAfO4BdP/oJVTauYnHAcXuexrmUd61vWx27m2OTbOCb9Ttau/QO/f+TLPLElPgjQ93P4YUDLSacdTDKViP2OZdtu4RUtTxUe54OBLVX6fq7bbwI7/Q2Fx+0dwfubDx1ZuTIILPjuzR8ozFMzo5YPNN9Bw47SzFTjja6TD718prZUNP2ZCwK/opcB+hrUVo3fFfxGumwQVL11axDM2h5mm+pJvnqkJYPvVaYs1KJ+VQMuv4NSdv/AM3dtKHkc7Svzz86PZE37/KO/w0vUsM8JpcFXFhPeccdLXlEIaHaxgb8WNqk4zY9k1VrGUXDmNNjwWK9Bbc6sZCcs2g0k022Y89mVXVSxvItp9wV7/T8Asok0fz3tDfztxcE8mycF78WutqDfvr72UdpfdBwtUw8pWT4ZlljNkeKiKZ/hHL4XPLdwW44EiWrlRzvWxY+vaHfp67neDq4yX/ylql3738WEVz8SO62RmYVhnwReR5aTJ6fYNxLUlkkEwUaNWzvIpGtonjy9uM2yt/rpF4IynYdu21gyfvuUyt32aPa1H1LH+V4n3WFgaVymtle+6hr2nbe0ZLlC28PPRrRB+UDUOhJEO+b2CUHQZ4d181wy6PPyQendCdg0oXL9XiLFXRedx0Xf+RzL951NxQ4X0FqWZS1Zky38VjzReADr/7ogNqjtb695JxtnzKElGX5OzpxW+tycH9wI05hjy94HlEzL+GGmtroG8kngWucdT/Idv2KiH2Ss3VFb+nw2HXF5YTj6E7FybnHdrbWVgZE9yaWDrHifWb6J/znzYlxFuC1868gDuM4+Qme3x9bHZ5Dv7v3OTj525jnUTwxLKhssm7CGhrrJdHkjV76+N4M5Wpgf/q8j+CU0YCKwf2Ra3H+heqa2nu+PExERGTLzGbl+fKNzbu8e/j9UvoCZHQRcF7ZpAfBi59w0gls+8mfzPgl8e4BtGhTnOzIxQW37nLCtcCeUiIjIMJvPyPTl4y44HcB3XskJxywpzNygT46LiIj00XxG8Ny6mSWAv4Xbe7SXeVPAP8PtbQXe7JybFLbvg0Ar8FKIqa00wvyyi4dZggtxcdmY4lTL1Fa1/Gg+eCVZU/2mdQHAj5QLSyR73uXrbXrT9g6WPNi3snDVNF56GQCZtWsHtZ7elF9EdGHwYy7jkaotvRyXTCfIxWRQ27m5jUNO/SE7s5+F7cvwn7+1Yp68tpzHSY8t5cmmYrbhefstZf7BvyU1oRjA19y6oF/Pw4sEfN566608/fTTrFu3jnTk+7C9czt3rLuD29eWZkIqBLVVyThWKVjppqauPrcvU3YVP9fYRfOd8cFgTNqL7bPDEmjJ0pKovvN505RupiUd8ya0M/3Q+3jRe77GqZv/o89tiVZfSkQy29y48SXBQKSt2bDk4a3r/sXCbQsBaOxq5Gt7dfH5Od0kcLznH+/pcXNr1p7LV/bqpiZyMbGubr/CcHPzU4VgyUQy/hLw1AMeY/I+LRx22rrCuFwY1JZMl34mXzh4Es92XQvA/fffT9ddXUzNTGVCwuF5SdragoCMw1NH8TTHAzChrpXM9Dk0t477LNjz0XXyoRUG1MzyggCc55LrmZSZEpYfjQS1DbIPdp2l5UcL44HFvIhcTEaxF177dZrm3U8u1Uou1Q5hQFiO0iCZ2tq7mTg7Xzoy+J5W6+WC4LPSTG2O0iyX2fRkLFH6m2cYixaVBo1tnrEXqxra+Nn9qytKdkYbYT2c89i5djI8dXHVoLZsIVNb9fCSZLoViwmoqWbphCBI7ZqjP8GOGdN4bnZpeceP/uMjAMyatYEpU3Zw5NQjS6anwtKWOZIsrj2GZ+yEoI2R9yUuU1s2V4uxpWJ8Sds4imd5KQ17B5ev7uBUdkUyq5Ur3y8FcJZj+xFXUjO/GGS25EXHFoZ3RYLaHAlO7E6TtiCwKK8rH0CY6OSGD3ycCz9yRmQDpe91hx9k50uXjc8mK9/T6Pv4OpL8v/ccx48/87VgWkymtlQqyyGHLIx9//PZzuami0Hhudo6slNnhCVji+15/b4fKgw/kQ6zF4b7Q98/po7TXlssI1tYfzLJc3ffQSr8ylpM4GZ5GV1H8eaCqTVzmDfhoKCkZozbjnk1Vx48pbDcQVsdr1juh49z1J/1WiY9lKImUbof0e1PAiA1d1VkbCc2aycr3/JJOmYspyNV+rlomlssmx7NlvfAi19aGL7ypLfGtrOaxMs/A0Dr9BNZMLeOlW/5VMU8HeE+gR/ujybC92R7fQOb584rzNfVvJHVk9P85rhXcfE+u0+qtlTvs1T1ySFrxR5IsWsiIjLKdvd+/CxgElAPvNM51wTgnGsDfmRmexNcJP+BmV3knOv77ZxDwDmPnKWoKbuO73wb9EG1iIhIH41UX77ROTe/PwvEBKd/yjm30swmEwSk/y9B+5cDvxza5vaN7/sVmdqC84Q6WhcRkREx0sfkXwFeBVwJrAZe2cO8HweODoff65x7FMA55wPXhgFyVwGnmtkbnXP3DF+ze+bK7hDPkqaO7kgZvV6Wj5bIdJEsML1maqspyc4klaKnRuIzxhT1VlbzpnOepqMlwwNXreDTvz6Zukl9K2tZtpHgbw8X4oeCc6WBEOvXr2XatFmxmdqS6QT+pMu5595r2brlx9TWXcusWSvYp/aB4kyJJB7Vn+/TLR2s68zwszVbOCYcN3t2ENyVmlA8Vbax4cu8iNIEUc45lixZwhFHHFGx3kymWBI2GwZ9mBltDV0wufQ1XLJzCacefGrhcZcXBKft6t5FxstQk+y5WrEffpd+dvtKbji8OP6vi//K/GnzeeMBb6xYprz8aP0vnyymTyo3cSaNM4M21KRnlkzqyHbQmDPmpB0TazuZuneQuWxaOsdJ697VY7sLIlkbE6mYQJDOXTB9f3zfp62tNZgv0vzWTCtzwmjBugR0+JDLBfM98OBxHHbo9znggE9XPq3I2zBhwgF0dQUZ4Z5+5sNMnHAY8J1CwOjs/abQ0hC8L6mJO9n3pL9WrO+ev/2Od++8ikT6FVWeZ/B5AZiSncIEa8DL1ZDpnkRH82R+N++7AFzp3suEiUFQRWtr30pBj2G7+/n1MSefqe3UXBDc+UR6Nce1viosP1r80Of7745cippMhlRN/6qi+93BOf2ORx/Da2vHD4PcVvvzeSxxPK+6917e8pa3lCyTq2ti21GXsH3nR4O2JoNfXb/sp2fGa66MnGkIvtt+bRN0TISyLFG+l6VjejsOsMK5iNLf/EzNVFzZRswS3HTTTfC600rGn+XVscu18amWyhLpDmPBq1/FtEQXXWUZrQAS+Czc9C5ealm6M/FlOfOBSw5KsvQ4ayquJ92OuSmxy1eN7gNWzj4qdnytH7y3Rx4V9I1TNp7C/4bZ2L7Nz0iGSQdaNr8civG9eGFQm0+C2trK36LGXQcyYWrPwdRnW5Bb4ROp2/iw3QDAI+7kqvM3MqtinJ+svA/09je8j4+4a4CgZGZe/hyVmZVkI253KXLdWRqmXM2mif9Vsq5Nlz7Lft8Ofrd3MR0//PjUlAWW75xcmn0MgvKcrzz6Gm5d8Um+NC/IjPfkkcfiJdJkk6UhRO01dexgDrNooLWuMqOhl0iQnOpz0qx3FsY1HjgfgIk7IZHwaWEqE+jAiwl6PP+eVXyINA/PiQ9d8sKgvNZJU5nS3lKSSe4Lz5/D+UedgSsLMI1+3k6Y8zaaEh28Ykf42Y/Z118ytQWYwep/zOUXHUHf/v7vBZ/5H82ez7EuxfYppRnUGnIHcMg7vwOtxWA33+2kc2aQqbRt9iIy7S8pWSYXCc9qmbES6Lly9T28mVs5jf/hh8wiPuPww8ccy8uenVSyjXzAZ6Fd4XfWqwlemInd0zmmfS77bS8t5dqZMlJdwXv89IwB7HMPkwEHtTnnLh3Khuxpcsn4l16nz0VEZCTszv24mU0iSNkOcH4+oK3MzwiC2qYCpwEXj0jjQuaCHcM6Sg8QfT9RuAtXRERkOO3OfTm7eXA6hOUDSjK1pclOnkpqp47Kx6KFd6wjmUpw3JsO6H1mEZHdwEj242Gw+dnATuAbwJd6WeTj4d/78gFtZa4J13cQ8DFg1ILayi+JZQkufOb6Wn40EpjmezmSqfDCTWR3oOSaVyFTW1qZ2noRDVTrLWjNL8soUxJgCHR3Fi/KbfjD1RzypfeTnFKaKaM3+UwdlujhivoQ8LOlF8gvv/wSfD/NPplTSNWWlR9NJ7DpQQasXO469pm5FOegs6OzUGOpq7UDz6WZMHslqbpW4A0l68iX4YyGc1g+0CCmxFbU8uXLueGG63nta19fbL+fIZGoKQSytdZO4KEps9mfdXieF5YHywc1GIZj3uR5Jevt9oIL+N996LtcsfQKrn7n1YVpG1o2sLxxOa+Z9xompoMLpt25YFtfPPZi1q94Fwe++Bg83+Pcp88FYPHHF1OuvjsmC1zZx+wb932Dw2YcxhcjWXXKgw7bsm10OgMcU2q6sESwXufVcNyOymA6AHaWVY+Mlh+NyWzDn0+GM5t58MEHeeiFjUxKpkiWR8GEJpijA+OBB48jlQoCHRavvYTM7A9XzLtXJKNabc1eJdM6OoOMMclU8F69/sMvJpFrZfWSLtIT40uCbl+/DH+ykaqNP6+54JHXMnXaK2lomEidV8fEBOS8MDum1Rbm6+yczIQJbVjSo61tfAe17ebH5GNTlWTu1cqPnr/qlcw7+4d88Me/6Ndm8pnaAFpuvZXutWuhro62rokwEbY/8QSZI4+sXNAvfsefX1/HDAySHkSCaTySpMKSmBh4qXaa3/BN9lr1BrY/UxqQ9EzbHzn3ze/jpBe6ONSeAGBuo8Gc4Cctm24J2lse1FYlOqy1JvhOtmeyOOD5fQ+iax3U+cFSm/bfnymJDNtiljUc2fREzvJv47RNlb+xDvj3jCAI2pmVvlVWfD0TNW3gJsfGQVQrzwmQcH5JdjWAlhTsmvqKkvKfWw+6n2ctyErlfEhZ8Frvky1GtD3FywulKB3G5MmVp5zmzlnJ3DdVbU6JaOnOaGa1clts/4pxfjI+cC4I03SF4LtgXDFwM5qp7QsTT+HpR56HsoA2gCvrHmLfy5az37E1fNn+yqF7BX1UuizbYFe6+DudfzVnzNpKKpXl8UOOZMOEYHrST/D0S79BJl0azNQ4eRpf5wK+6H5LdzomiDTl85IPruS+RxfwprbSwL8EDjOfL9jFHOOe4eeRPfgaF3xOPK8ZmF253vzrkUixae8DuPq00zn1nuvZPr2YzW2Gt5Oky+GVFaiMJmXzzPFwenlkYuW+6eSZDbTP2oTfWQMU+8J9mw9l3/aD+L+TSgPa2ifOZU3ipRwy8TqilYsTCVfcBzOfXNnvWjSobdNx5wMXVX3eAH+zzwPwsHsd7+am2Hl+feQkWn9dLLF+IV/ki/y+ZJ6m8H3zSdIyeX9ev+grHDVpBzccUvpeN9emmRR+fMqzzI2m3Sdn3B7GS1aLbNx9PhwiIiKj5DVAfg/x9rgZnHPrgGXhw7fEzTOcfC+Hw0hSeqLH+YaXU1CbiIjsufoRnA7F4PQR5zuv5IRhjjQkrHDBU8aWx25ew4K/rx7tZoiI7K4uIgg2/6ZzLj71RsjMJgKvDh9WOx53wB3hwxE/Hi9pS9mp9Hz5Ua+P5UejZcf9yLF8dH+g/bGwNNWu9XDT6cFwsqYkO5NUcv0Iaisvk1Ye5JaMlCed2HQQ237zaJj1qh+lDfPvaZhlBi8HW56JnTWbbeaeew9h8+ZrWLt2LY2N8Vkx4vheaUaWfIBZLhOTqS1V3Bfd/4DnC8NLXlhYGP7rOa2s6jqZA9/wK+a96gIA2tvX8PzSM7j3yue5+c9BwFcNsHHGHJ6Yf0Rhm67sC+L73WSzTYXHDTt/zcmvvZKWlpbCOM/rDF+DIKDhtqNfxW0z96MjXUsmk2FKRzSYM3g+ibLsd7lIOc4lO5eUTPv+w9/nWw98i5tWBxdlc7lWWpvuLUx/8v7gAuzG1o305P7GoM17dUVTApbOc/eGuzl/0fngFbPObdx0KZs2XVl43JZpK3w0jpm/mPSknYV1bZu8Ln7jz1yBB9wyeRIdZvDsldC0AQDLVQ/iWrFiRbDqdA0pL/46YF3kpcxna/u+9wNe8/jyinknJGD2rDcwdepxtLbGB1k8v62FCx54gcuf2cjlzwbvRTrZEjtvIu2T7U6QrPNoZTJPcmLJ9K7uLey1VxDDXJurDYLacsEF8lSqGACTyQRX9lPpXP++oyJQCFxrp7VkfHn5US/Sf29e/jz90b1mDZ2R0p3Xr2ymOyx9aOEPQveaNWz8ylc59rjSXSHzi8Eoz66so3HmERWZ2qJBSs4cXjrYJ5m8z3Nk2m8n11Xse9blggyL9TNnkk4HwU/J8Ce01abx8/83n22zZtOcmE49ewfrxC8J8IvK/+y3ZnK8MGceDx92LBcdEgYghctYlXMeCXz8VJLD6uL3bxZzHH5YltRV2T5AItUJLkd3TW3FtGxc4G/IYtL+/OjoCazY592siFSj7Nz7+ZKl8tdncpHzO7+17/IX+2LQ1iGIu6jNFX/jGq164FVU/tn4qcpMbQCdTORW3s0DVgygdpZg8l5LwuWL7X46NbfHbdW3bmUzQUDd6rCca41XWUK3XL705dRc8fuW9qAxuYbO2vibB+4hviymSwb7PA0TKku6umS2UAL2OXtpSaY2H5/OJNx2/CQWzij9fOzjiqXnvWSSplnBc9y+72Eln5eaZJYEfuE4oCDhSCRymHkV2eFqayv7pyxpuqauqwiufdfSr3DC1spA967a6SUZC/Ms4cjlv2fmyJRFY+XCdprzKgI5e/IQp/Ab/jt22hu2ln7OnqJK1lXAI0Xb5L2xRAMXHLMfPzuq9L3uqJlUuAmko+/NG3YKahslcbWIRURExqk5ZrbQzNrMrNPM1pjZFWb2+irzR/PxLqkyT3RafG7qYeRcBoeRqAhqS5D1dGJbRET2aLt9cDoEQW2lmdpSGE5BbSIiMq6Y2WeBNwJ3O+cu68MiR1C8ZtCX4/G9zax6yophlr889bqwAmo+U5vXx0xtLnL87kUv/kV2B9ofrw8GNj5eHJmsUaa2XpRkavN63r8qn+7lSl/bRBj8FVZLwu9MsWDBAs455xzWrFnT1wYFf/MXKu/+EVz4emhYVZila9kyvLY2urqCi6ibNl/OpZdeyu9//3tWr17NsmXLSlbpnGNX05Ml+49Zv7lknvxFXB9YVVf6PFM18RfaWzpKg+gWdxRLezrneH7pN6mvv4m1Sx4jF15mqsFx2zGv5ukDX1wIakskSzPtLFr0WR586PjC40zmvnCo+D2497prePj6VYXyo12RbCxNDa1k0pGiehYEd2RW31W9ZC+wrX1bIUgtn8WtsauRtraVPPDgcSXzzqnN0nznOhY0NtA56XVV19kZfmZS0Y+Kc7TNfpa22c+WzhwJamtvX8WKlf9beNzSuYkDa302M49WpoTZ8GDX5I1kqmTXAbh66hQeaDyDKzs/F4zYHAQiJtY/XJhnRk1pgFs6zHrjEkmSVYLa3rzUq3gtt9neVdux774fYOKEs3j8ibUxUx3nP7aOn9++nJ/+azl12U5SE3cyef5TsetKpH22PjONVJ3H7/g259p/01JWotD3g/evzq9johWD2tavP7YwT6Y7OBRM12Q4dEb/SkKK5H+jm8tK7DnnY5EAWuf7ZFLG/q/dgiX71x+vOfUdJY9vX9dORyb/OxgGBWNsSh/G1KkNpc3zS7OPeXNz+GVBU14kC5MzR+f01WGbk/iZZeQ6g9/eiXstI0fw+5S0HLP2CoJjN0w5qGR9yw45jDOP+RXfsj/ikeDnR9bSNHl67HMrBLV1Z8mE2Wdbwt/t/PmPRJX9F8Php1JVf867IzlBd02ayq5IFsyS9SQyNLpHyNRUBkVl05WBboXlYtrVUBsG1iSK09Kp4m+6c8ZzHAeAVyUTq18WCrOVfVjB4bHzhgtUKL+Joi8K5U9T8cHO7UzmavtYxfgDXxkUJPKs759rM5+NlGatT/VwjSr/dJZMOJJdTCdnxZiVtOfwup8hm4wPIVphRzK9vZVUWdBcvhxoMtz3WJXYCvjstdcL7Jy+Exepu909+3lyiQQOyJnPNft0sXrGXty8X2lQWprie71j1t407hdkT5xWM7ckOLMmmcHw6aLsM5dwvPo1VzPn5YtYNaX0u7vPfpU3RQZBcQ5L1ZHarzSwOy5hWS4V38ftmrmBp1LB/qnDZ8XE0n3VR3lN0Dz8kiDY3my1eSy00nbNybVS6zmmZUrf7/JkHCXtJoX3oeUc/v6fsHNCZRKuriR44Wdi06QUbbvW97mNw2nIgtosMNPM9jezA6r9H6rtjXXd1T6jOoEuIiKjYJj78YkEheEzBPseBwEfBu4zs7+ZWXku6n3Dv7ucc51Ul79VY98e5hkWzu/CJ0Gi7CjH+UYuG1MCQUREZJgNY18+7oLTIV9+NEHC5e/qTQd3WOoCtYiIjILh6MfNbB7wK6AT+FwfF4seX2+uOlfptBE/Js/Ln0nPX/TKhheS1647r0+B6iWZ2qIX/3pbNpkuBkntwZxznHnmmdx1112V0yJBbeWZ2MqVZ3Jbv7i0PGI+U9vbpxUvvK1eHVyMvOyyy1i/fj3/+Mc/Yt9z5zueeODntBwWBkjk3+f1jwR/u5rDNnqsfc//Y9MXvkhLrvLC6BVXXMG1115beJzNNrFh4195+ukPsm3bP8Pn4fP05EtKlrPwQvyCI+o4I93KTUtX0tAQBEmk6ppiX4+u7urZvrLZSJYtg1w+i102ExkdBrWlS4OyGnctiF3n8uXFzHCpfX7J4gdW0dW1q7CNgGNHcztbZkZO4eWD2lbdBbvigqoCb/r7mzj1xiAwzwv3vdsybSxe8pWKeSeks7Teu5FvrUvRNusz4Iy/X/E8H318FW2RbIrZ8L3eMjHB0qnBZc6d8//B5pedy+aXncuKt3yCD84IXpPFbZtKtrGR/XmoMQhea958ER1M5Dv2e77LbwvzeKkuavw0Ty76PK1tQZY038/R3b0DcDxTW8MhjceRaQoz1njBucDO4ttA1i+9CFhTE178TiTKMrUVP7enrHQcuD3+dcz7B+8pDK96IktXVxfOj7ngaD4z2rfz2k3Pkvay1GbbOfSd32XqgQsr5wWSaR/PS5Cqy1HPPsFzoPSUbSIRvAcpP8WEhCsEtTXsmF+Y56H0yXgkmLHXNvaeuGdVptJ18iEQZtNMlJcRjGRqczh857Nm/kRmHdHMzBc3V6ymPybTTjosYVn4xBp0JKdXzOvKyjqvP+GVFUFTpZnajPqjLwwfBOO3z5zLjSdNYt7rzy1kaXph+oF8jGtxwD8OeH/J+lJecX/jBQ7jhv3ruPGU0sC8ouAZtGVzhV8Wh+OFRD0vHBYEyKYT8ZnDwLHmMEhGfk9u4f9xL0GNzmTZdZAfFRLwF61jPle+6NV0J1rwrTIEJVPTv0xteblIgFcqEtR2G+/ieTsGgGwff27OsPM4y86uvi2/pqIl+QDB/shn49rwip8Uxs12xR/4u6vc32lhOc5Nx/2xT9t58sDDSSRzbOTAkvH7NDdUWaIY4PjolJP4Lr8lkygGZ6W84NuWS1WWj82b29pIomw/OBcmc0omgmC3DckG9tl3JS8+/BH23mc1LpJ1d9dLr+IvJ7+LZ/Y/DICGMNvn5KxXUmo2RTFw7h9v+S8ePyh4js5KMw7WprtJ4Oh0kRqgQCIVfK/PmnAW/31SaWnY8mBUCILavESWxInvp+uVn+bH3z+fV7eeHLal0sTD3w5WGTzWPn1jIVuuZw43rTRR9hbmhW1I9CtTW5yk80k6yJU9nehrV+63fAfv0FY8EiRqplZM70pYcKwT6khNqJhnNAw6qM3M3mlmdwItwA5gHbC2yv8+3jYz/mX2rH05ERHZTQ1zP74F+DFwLFDnnJtJEOD2auDucJ5PQuSsUWBK+Lf6WbzS6VPiJprZ6Wb2lJk9tWNHjxVW+s33ghODibJDHOcbmawytYmIyMgZgWPycRecDuDj4WPUFC6CB3dkKlPb2LPonp7LU4mI7M6GuR//MzANONM519dlo8fXPR2TR6fFHpPD8B6XA/hhRqpUmI3AhZc7OjrW0Na2rOpyheX94vG7n+utTFPkhL4ytQHghQFiCxYUg6W2bNlCZ2dnSfa15x+uLEUV5Xulr+Wdf32elbtWFh5bTNqUQoAQcPHFF/P0008X2hO1dlEDrd5FNLwlyDLRtWwZuV27IBde1E8FWWNcd/C4dcUTHP9sjq9xfo9tfvCh41m9Orig39G5DoAnn3ySCRNKSzvms6btmBpctPz7/Q9y3nnnAZCetC123WaRz2LZxdL2tq2REnyOTJg65O7m4lcyXwqvbsa62PXX1/+D5uathQuuiUTpV/2wd3+dNWv/I9hCmDXpkBc9wdKuLNmUccD2bLj14Dl5KWP1xgtoa2rngi/fx9zW+bHbhWJp0rZsGwmrvJDbmmjnd3OKpTbfN2sy1056mrs62rmuvpi5KRvZZ//YKycB0Hjgv0vWddLkYFsf3XgDucjl6O/aubxv0QsAPJ6Zz2ftcgCarJh1yE91MaWulZadd/Hc4i8DsGr12Ty84CRyZMiZMefY65l+6H3Uz6kBL0NnWytL1hUDCbu80sOk/GfWJZIk/cil2eQsPstlbGR/3ERHXbbn45Fr7SMs4WgA7ngqx87mDM5VXuq1hMePHjmf7z11BT955CIm0HMp0ETKp2lSHclI6cHf8L3SecIgzdk1s5lROwEvV8Pc+vqS4IAbZr6H+3gTB754GZmung4Hxw9dJx9C4W+ON309LvJb6JxPvh92VhqUbjHl/6qJO97/ZvIGJlvwO5gPlHFB3rKKeXORWqMOhyU8XNlvWfT3Jj/7Eo6mPQy4+eebP8DzB9ayhXllAXBJrqIycxeRTErJMFDFS8QHHOV/s9uyxddul7VxX83zrDsoKJs5Y+rW+GVJ0D7NMTkzrTDuOvswf7UvAFRUrNlpcyrWcT5fZdGsg9k5Yw5eXPnRydXLaCZ7OBcTLR2Zrin+zl6T/GhhOFcl4qU86LA3H09fzaV8pmRcV6p6hrlqzmm7qGLcFIr7CLfZabHLrQ+D03Lpvv1+Lpx/OCeedCOb2a8w7rBtDew/8YWqy3RF3ps2m0pnohi0VGMdtBxxfNUsZACTU80kyt6v/Oe+rq6djhlBPz5pUhAgbzii3d4iXgrAEwcH97ha+B1qoa0kK94+xO8/lofYzD54Fwk8uigNvpo+u3T5dLqTKVODwMKL53yUcllq2HXIP3niQ7fw/lNy3L//dKZMPY305HqSMXE9k/Y+FEtU7nsurTmcRVOC5/Zf+3+Kf8wozTzrCr9lSRby8tjn2FcJHCkHmbJMhckegtrqbV++wR/5mF3PczMq98W6rZ1UOqj5e6b7HhPjAudHwaCC2szsl8AtwJuASQSfo57+93l7ZvYJM3N9+P+mHtZxiJn92czWmlmXme0ws3+b2XsH/qyHhpeK/wAMRW1nERGRvhjOfhzAOXenc+5M59xzzrnucJznnHsEeGu4bYAvmtlhQ/CUyrd/oXPuBOfcCXPmVB5kDYqfDQ6Iyo5tfZcg6/V2IlxEpA92rISL3lDIHCASZ5j78lENTofhvRDuXHD3aT6oLUcaM2jvVj8+1jx8/areZxIR2Q0N87n1jwDvAJ4FfjOU7e6PYT0up5hlIR/0VHpuvfeL3K5qprZeFkzWgNMNbfkSlVEXXnghl156aUn2tXXPVc8WApWZ2gD+8txfCsPlWfIBamsrLzDHBbWVlzKt//FZrH3P/4Nc/qJ48Jnxw6C2zGHB/G02tTCtN84F+4/t7a0V0/LlR/MxF9HPqKXjy1vuP//B4jxlJUS7O5uLJVSBzrCEaVekpFuyLnguc46+hTjPL/0GTy38Ol4YdDVjRvGib6ZtDpYsvo75d2barHrWtjcBsF9DLv8EguX3TrJ+5w28sOxmvJzjHezFm6fEVzHwwkDS1kwrydSkiukNiRYWzp1VePynyX9i+rRgX291RzG7UDbmM5Pw44MOvJr5fNyu5T7eyLPhhXSAnZkc52beF7uMS3aTCtfnh+/vjh13ApBzGebPglkvvpO9X3YVzx8xFbwMXa3FYIXDt+wk55JsbA+CQ7qzOfzwor1LpgqZ2rzkLHbM+x0dNok7ORVvGpx1dfH130nxtYj6mZ1JJ3Vc+Nr9+Z2roaOz8pDKzCOdbWPLnzLs/x8rqbOeg9qSaY8H6g5i1V6Hs8uC7a6zgyvWCTBhVx0J10kul2ZKSyvZsow+GWrpbJ9EXUzg4ngz3OfX9zRmRnaeT9uJf+GRI35XNq340vnOFX5X+3NZ3b/qU8X1JX0c0Fx/LLnu4DNcyP5kxAavl2ZFdLEBLbmS8qNGM1P5mZ3Jnyd9orQtJCpKD/7L3l2xvk2zi4Fg+ZKCW+bMZfG8gyvmzQe1rVjyTGHYle3UJGMyS+XbEwQIxr+gPWVSy5tAEIjVNWESubrK7E6XnnBS1WVTPfxeeJGAutra+FNNGybGf7Wi/W79svjsaEvvehfJ1n0L+5V32dup33poYXq0FHecd7ibK8YtmzKxYpwjwUnNwbmtl7r4UtDfmfA/bD3qr/0Kxmtgr5IMs3NnLeXoo+/p8/JdyeKyvp9h27T4vidvn1kvVJSx7bKJbGR/Djn0STa+/Oc4fGpqgs9DLleDH4kKywdyTe4K3ksXZmhMutLP2at4mNPc9RXbd4CfKL4+STwS+BVBbZ02kQv5YuHxS1/2L447LgiAXzXhUMp1ELxnZ9h57LKZANTvt5BDTv0hzcnKYNAH06uYkS7NfNjEdP405cvcuM87WcRxtCcqy/DmtwNwF2+rmN4fLtVOynf8/aDSfaqeMrUBNIXPL05XEnJhkFzaz5HtR+DwcBpw52lmbwPOAHLh33zJkB3AocBrCE6ANwINwH8Q3NHdXz6wrYf/sXkyzexU4DngdGB+ON9M4C3A38M7ykctgsxViaIWEREZCSPYj8dywe1VZ4QPE+H68/JnASv3/Evlp1eeNRxm5nfjMLLt00vG+56RzehiuIgMgft+ApsXwuq+n4TYnWW6cnS0VF70koEb7r58tIPTw+0N24VwR1B+NB3J1Gb4eDEXyERERIbacPbjZjYXOBfwgM+6fMRN30SPr3s6Jo9OG/Fj8nL5i7zRbEGVyWQrRQPZohmFXG/7A2M8U9sVP3yUp/61bkDLOucKr080qM05x7333gtAfX19Rfa1nkSzurVPXkfj7CfZ1rEN3/PZuLyRZKryMlY0U1thPTElYdO1xYvkXYcFAQy5+vpiUFuYOax9QVCO1Lqjl4z6GtQWbtfur5iWvzibb4UfuSTV7scH+82as7QwnEiUBodl2neR7c5/bh3tdZVtrJbBp6Rd1kwmE1xoPfiQSPnRSMYvFzQgWCdJGpPBeme2hZkRLcVkEuTfvoz3AiRyHHPk/bxjellQmwuCSPOZ2g72FtPc/DT1ndNKZkskPCbkSo8bJ9EOwN82B69X/ZpmunOVQRkJLz7owCWDC7d38zY2Uyw/dtSCJbHzA/jJbtJ+8Hz9sgDWLt/jmLJDk+aWzpLP/NzmoM0t2SAw7od/X8iNi4LMfH5NLckwqK1p7g8Ky7QzGW+6w4/8ul7Pf1Vt48J/BwE/qzzIZiby2KP/WTJ9le0gEba980Sf13/yX7Hr8bKGl0mTSAdv5AX7f7PqNhMJx9YJW8MypB65XA2T29roTpaW5su1TcB5SfbaGJ8RarwY7fPr41IigR8kCCI5qXhjm8Mvlh+14Hc3H2dhib4fw3vPlAb77ph9LM/P+xhddUEQj5/MkE53BgFhcauNBBo78wqBniXbiGZfS0B3GGizNZkPTguex1oOqQhqi7Nhzj6F4VQkuGvBocdUXWahl+Phw44NlinL5Ji0+N1CnwSYT11uIms5qCTwBvLZ7XuWD2rbuM9BXHnqx3udP+823lVREWd2d/G5euGb/XN+yK/4fuw6lkyPfy2bbGbhuexY/arYeXw/QUeqteT96OqaXBjO9FCK8zdd3+ZVD9fy3mfurpi2itJTZT4JHFkOcStLgh/L1c97il/Y/1adXm4XM0rafniyev8WpyOSqS3le2wJg9re466Lnb+GDMmYfa7fFy73Bd+PZDL4rFnCLwS1JV2xxHUm3K/IhB9Rq2krCWqrpYtjeKZiOw7DSxafrxHcPFBeOv4B3sAD9sbi+qoEROa1MLWiLGkT01nNYTw7ZUXF/KvTO6idVpp1tzVy3+6DnBK7na2RghVxGQ/7w2E9ZjkciOyEzkI505SfINHD538kDSYi/HMEP+n/55z7jXMun8/bc86tcc494pz7MXAc0Az8lSoBaL3Y6Jzbu4f/D5UvYGYHAdcRHFwvAF7snJtGkG79rHC2TwLfHkB7hkT0y1ZC589FRGRkjFQ/XpVzbjXBAT1A9Nai/C2iM8ysp4Lt88rmHzHOBUFt5pfu5PouSTYXfzeqiEj/FEvKjAfX/+wpLv7Ow6PdjPFm1PrysR6cDsFFtWimtizp8Gs3Pr5zIruVTU9BR2Pv84nsWYazH/85MAu4EFhuZpOj/4FC5EdkfH5c9Ph6HtVFp434MXle/iJnMszkFc1q0ZdYvmimtu6OyIWuuN2B6P3xu2FQWy7jcfNvn6FhU8/ZmACad3Ty+D8GVgHvn79/lj998T6gNKht586dPPjgg5H5FpUs55yj+ZZbyO3cWbHOaFBbx+QNeKlO0ok0i+7dxD/OfZZdOyvfy1TMBTbP89jeXs+aDX/D84Kvi7+zGFTT+I0c954yj0dO+n8sagyzxfg5Mhs3suWMYNfWRa/Z9/Ei4a5cgnPWbuUq/2Du5O14kc9hvlzj5CnBVywVlk1rampifcvyypWVOWTi4pLHmY5dNG4JAqbMHO01la9NtocL5XlmaTLdlZnSkhOaCsN/ft1pZMIAOZ8knYkk6ZxjYndYns9qqcHoCuMOWjKXst+r4su2vmHhHH7zX+/i2IcTTGtLcnRyAwBPdZdeYE4kc8VMSaHayE9fZ2uGG365kPpNMVnxvODNW8dBLOK4YFlzJBLBtbgMaZqYHtu+ci7VTTr8yrdlWtnathUvDMj7TeviivmvWfkISxYXSx7nL/Z7YTDJwtWbSYY/LH5NHUnf8BNT8VPFi9nd1NDxOp9tP48EzfQQWNk0IQiYm5wJ3oBcrjSory7XXJKhqTzwZ/ElQbCFGfi5NIl0337TDCOVCr77fjZFTWcXN73stSXzPFF7IpZ2dM/bN24V48mon18fd0py0RSHfeeKQW04fN8v/FaYwYaWDWxo2dDr6r1MNCzCyIYl9vIlRKe9bSnHn/APALr9ynP8ue5ioJMjB71kattOTWHfJOl8vNoJ+Kngt+oi+xJ+H4LaStfdt/mfPOzwwnB5UFs+g1PaK31++UxtPsb/2DmF0szFbfc9qG3loUf3Om8qUu3mn5xWCGo7sSHHq90DJNONhV8wP9zPW2zH8awdH7u+nvLnns9XAehMrY6d7kiwa8tRJYFhzc3FDHnZZPV+1SdLLjuBZK7y9/pM+zk7mRmZN4GZRw2ZHoMEf8UPqk6L08kEcqQ41j3N19yveB339mv57mQx02nC98mk0qS8HP/JtXzP/bhi/hoyFZnaoCzwMeEVypzPnfsC02bWB6Px6A6Dz7KpNHvtvYpdE8N9tX1K9x1r6CYdl3HM4OmjgwDFWi/cF/USdFtpxtZ2KvdzABK5yuxpAJ6lCwF3eU/aK/mR/ZyuVOX7tfiQA1l1WPEw6F7ezOMUAycfs9fEbqfdqhas4GXuyarTYttMcsiD2jKHP0Xz7CAwMu0M9//ZO+8wu4mz7f9Gp21f914xGBuMMb23JKSQBgmk8YYUkpAGH7xvOoQQII1AEjqEFnoLYCBgqsE27rj3uuvtfffsnq4y3x+SjqRzdHbX2Abb2fu6fHmPNJJG0miemee5534K5fb9kLEntTjR+j83KbDnq5VS1gE/BUYAv9yD6+0OrseUeW0CPiel3GrVJSal/B3mhB7gaiHE4A+pTh5IsX80gAEMYAADGMB/LfZnO+5eSjKjl3L2vg37sC6+kIZmktpyxotSCDI+q0UHMIABDOBgRHLDBjoeebTvgkBXs/9qOMMwiMX6DrwNwBcfqS0/kMnpYDrCJYIIaYQ0SFHEkOLxfR84gAH8lyPZ000i2tX/A6SE+z8Oj+Sn0hnAnkMaBl3PPY9UBxbWHIDYl3bcVoH5ESZ5PPffr11l7W03Wb83QTbXY3/m401Syo+MtWqvM1OsUKZ0hTsMn2B03vFupbakm9TWl1JbCIz9a+7fVNVN/ZZOFjy9tddy8570Kk2kkxoLnt6Klunf/dRu6sz+vXjx4uzfO3f2TpJL1TbQ8MtfUX/lVXn73KQ2G0ERIhUrrPSs+vR7hmHw81fPoWr7H6iuvp1oOspba7xpq4LDwtROCvFa+hTrIA096qSNNIqduixoHkkutE7z/u/hp/yFawD4fMPHuLm6mf8ox/Kw+J4nlZSdmi5oqc2Nn7yOIUNruf6ef9JZ3jf5bHKxN71cffsSz7njRflxJhV/xTI3Yh2JvLR5NdWzkEF/vo2Ogi4EiiEJa+Yz+saRlxIWAdzrPcvGrM3+Panc4b5OaDHXs4xsDPDlRQ7RqUP3kgAGDWpGC3u3uUkG/353NgBp1RtMX1upcGHlP3iAy7ha3MxN4rcA/HZ0MpuyUCNEtL+ktkCakPVo42qM777+3SxBbEZFdV75Q6cu4Z2li7K/FasP0SwyyaRKhcF6FIDSouGEjDB60KvOEvHhOhV6lyO7G5l9shmsj1jfj5QBVq/6NDt3mISPYUW1GL00MV01n6saLyFUkmDo9ChC6Z3Ytp3DmH3CZewYYb7D0h6DhkHDSIa9BIGq8GTCxXF2yINerX1/9q8fkOgoK+NHF99EK97vQ2J40o9KQzoEdCH57Auf5bMvfLbvC7ibuHTIbG6EQhmkEI4Kpwuqiwyc7n7IN/2ou89SJ7Zkic4CSWLyEUgXQaq/JLXsNfEn4+RCU9y2wWtjpRAEpMo5NUs9203ClYEm/TuO3pTFbBRZpDY90nfZUVGH5C4R2X4TYRBEIyMU2pQe69p9k24NpTAJeBNHAJApc6Wddy+EIEB37XEsXPTV7LZqbUr27zXjCycnEFKjMdBFoMC40H5nHQyhk8Eo6ITIkOnFVm8V0wvu88MWpqMSIkyaE1mSp3oHcGRb7+NDG1IRNA+voMx69jNYS2kOAT1EJrugpCCEhrRs4KBBzQwfa44TAxikMclnUggmTF1NycgqAHYyxUPmjpD2TaNZV+Gsob1HucS8nJT0aF7110KktqLUsILVbmCc73bpk/xx7fBp3FXptJkHxA95QXyl4Ln7g8Hs3rTKQCHoM2/ZnfS1udAI0jHWHG8GdYVwsO9x5YeBPWFWDQUSUkq3rp6O/2rsN4EU0A+LsmcQQpQCX7Z+3i2l7PIp9ifr/wrg/H1dJz8EivxZmP3JST2AAQxgAAMYwF7AR27HhRBTAHsEWeXa9R5g5/3wTSovhJgI2KP7N/ZmvfoDaUhfaV+pCDR9IKA0gAMfd8zdxil/OjjSXh6wsCfLe3m11e7gkd8sYsnsHQX3V3/5Qpr/+MfdOud7z25Duu7pzTff5OabbyaZTPZylAMpdXQ9tVvXPIjxkdvyAtjvyekAukVQVzAoMtIkKKWyaGQ/k0wNYAD/vbjre9/g7h/8T/8PsNO7Na3tvdwAAIjFYjQ3N/dd0EL3K6/QePXVtD/wwD6s1QD2EfZLOy6lTGBmPoHC83GBmYocPoL5uBt24CuQJbW5VV36npt7ldri/b9wIIwZDd9/fPl2SlDRS1AXYP28es/v91+tZu07dWxa1HeawFTceabJZJJVq5yUULW1tb0e+5+HTLeP1t5Oz9y51P2/K/Pq7kZrTxuiuHDANLEjf56yePFiJiZMsk063cwd79zBjqiXbHfYOSapTwtaAVpd9bxH6eILPBXJJ2SntpsqLwvEOawVx5Agfw1HjIrs34qiM2HiGjLCfFYGAUpLunjipE9y34SfFLw/G7l8C038x/mh6KQi+e87V/1FpqfklSkZVE1lZatnW7RnaMF66FbSO0WSJbWFUzsoUgJQoM3dceaffbcrYSfw36PnHxsZEvX8dt/PthWbkEiKcuJo37UIXnPFJ7PbuhhEWQCERcTIEKYbb8C7IBQVYaUZHBqUlNSPRFr3PTTo/90XF0cZNqODWZdtQj3CDMLrlkrN5JI0IyImwUtRgghD5pHa9BwlFJUgS4V/qrzmitEkI2Z5N6mwp2c4qpXy9OjPv8CCs3sR3DQEVW8eSs28a0h1me7ZosG9k9Ae4bsgBK9MOZu/8hsO3d5ESdqZn5erjoLeDg4jWL6s1/MdBNgvbfmBjNenz6Jq+ERe57MeLpbpiXfSjxrSyO53c03enjuFDRv/r+D5peuDGX1CF5mwrbzm/a5FSPdVYZPudKOKzuAp7+aV0XPIX/bvgDRACKRw79s9UltuesVCyCXglFe0MOPMl6kYW8Mboc+gixCK8NpYAwWBRBP5ilQtjORdPp63PRdFmP2B7kMWzIVbldP2zZh1NwiR8ZB6VZ80r7uDYpK8v+JzrBjvKNi5VU2loRCWIQzXtpoh+cR2P9gqnMECpDabYHa5uM9U6ApkCKP2i4DeX7wkvkyDGE9QFn5OVw69nk/E+vb1t5QPoqloJF0uTahc7kqYDEUhc4FyUKp8ST4NQDEu8pti4G7sL2KmyA6gkaKIgKV+mqAkqwK4SczAcLUdk9SWP57fNtQZZ4Wt/QqSTI5SW7rAOtveCNxrLaXXXBRSTt1dtcW+sLt9goGS/XbcaBfD89Lf9hcagSyJNWwIiiIHPqmtG/JaUhQos4hlWVipSTR6lyzfWzgdsjOJOX4FpJTVmKvOAD7pV2Zfo7xiou/23uSEBzCAAQygN6xbt452Hwn/AQygAPapHbec3H3t/6v10wCyXjkpZRx4zvr5IyGEn8fJXtXWA8zub732GqRu2WzvgF4vKyej9Z3iZAAHNqKtiYKqU3sbnU1xutv6R/bZm7j5ja00RlNktP0rpc6BAi2jo6sH/rPr6Uix4rVdfZaTu9HvrXm7NpsuB2D9epP/lEr1j6i2Zu33mTd/Jpq2G0HHgxcf6Zz8QCanA2CAgUBgUKSniFOKwGAg/egABrCXkbHGTP0IbOyPuPWtbWxs6O674F7CXXfdxd13+6du84PebdZNa2nxbDcM+ZGMIQewW9hndlxKebaUUhT6B/zeVdbefqXrFA9b/58jhDjJ5xIX4ai0PtKfOu0rSEs+3VZq86huGH0rBBmuAGRmd9OPmhfpf2X3MWximLKbER/dmvPZamntHe9RV/+Eb9n5TzkqH1rOHCAQ6L2fb2k034dQDOp+/BN6Xn89u9jF0POf47B103nr9fd9z6Whs6W7GzAYPKQO+4UtXryYkTFTYaNuSzPqEpUhRSN8zyEVlZr0LNavVEmrGZ7+2lepHT/Oo9Rm+GTbMSIRDMO593by1T4MT/pRnYkT11JeXp/dpxt920Tdug9DURl9Uo4IlBUkFoqG4UOwyg2UC92s43N8hR/yYMFrZtJ+PByrPigYAgIGhKzbT8U3MrMkgwj4uwDTqXw7tGPCVChyyvuR2lKKNyi9mmOdeigKYPSLT9qMSUgIWR+FSogMYSKyb/s4rrwFoTjkuk/VfIpMondSxfEnvMS400xuU/RHFqlt5DEARKIO58lAUh6oQA96CRNKp7ddxCmjP2guDvHEiZ9g23DTREhXqsGpX6oueNzmKTNYHPo4emoY76+7giu4h8bD8hVqGhumZv92q2GuFsexcNhMgq6+4POLnZR3vxd/JFZyeL/u4QDG/honP2BhhxQk3ni5lBLF6pOlAKR0MqjkpNZtappNZ6c/odLuO8Z/eRhFQzNUT7I5ht5zTP7i/Dzii9BDSKFzxJFzOeSQ5Qyb1k643DsGh3xSik3MFRbxJOAi1O8usam/pDY3EiGFQ2ct5KfiAW469Irs9uGldZ5ydvpRP6W2q8RdbBLmukTRC3EqYKlqyX5QHSqTjl9PItCDZt8sFZ0I6ayaF4AaMDypvXcHp8r5RBlEkz6OZZOPzG73pFMVCgEUj92P+BDu/WCTroI+YxnIH1KKQDJPqW1crJFvysL2ub/ITd/tradOUWnf89pUqO82FiZDkfW+zuEtLuBZDpObqRGTuVg8x9N8g/GnPJhVMoxTymIrFaep1FZEmeUnSFJaUAVwMJ2+Sm02zpDvZP8WUvaaJhbgem4A4JhP3uS7PyhV3haf8t1nFAh3JkQp3+Ux0nuJpGj3H4P6KYStEyCDv0/9MeO7H7AOoWw9UqkelMD+kX1yT2pRD1QIIdyt257VnOYuKIQ4DCiDXlpeYQwXQqwQQsSEEEkhxE4hxGNCiLMLlHevBF9foIx735G9lNlnSMmBgPcABjCAvQcpJc899xz33ZerdD2A3YXUDOLLm3xXiR5k2Nd2fKIQYpkQ4jIhxCE2yU0IoQghTsYknl9glb1XSrkl5/hrgTgwGnjZqgNCiFIhxLXAD61yN0opO/mQIXXdV6nNKCpBHVBqO+jx2G+X8PjvlvRdcC/gieuW8ug1i/suuI/Q0jOgiPVBcO8V83ji93vaRj7axS5yN1QnjH6qrNmo2+x027qV8imT6V9akvb2eUipk8nkOw7/C7HPbPlBT04HDKkjrZXIRbqp1DawxmwA+xJNzS+zbbu/YslBjYyVYjoY6b3cfoiMZvD3t7by5bsX9V14LyFhkWr6a4eF5biXmje4tOzlnTx6zeIBYtv+jQ/Lt/5B8DCwDtMyPieE+LhVD0UIcRFOmrU5UsqPVN7ZDh9m1T32klKb/zfoGijYzLH9iNRm9FOprS+sXv0ttmz5re++TEojWdJAd8UWDMN770o/2XRCd5EHrXPUGxprJ3qDgUc1n8Hg5Cjfc7QKMyg7fsJ6Zsx4hyFDHPU5aUXSEz3m+1QCfu1AMmLcGl6N/y/z3oT2mhoAGj5djjbGRWojQCCQYdasVykuNglOajqNYTh9a9JHkMlwtZURI8y1H3aaLjMo3/c70lrMbkAqKpUTTXLGP/g5izg9W0YomkXy8iJXqU3PmApsz4uv0uM7NId5VVMxeiHbpSli05jJIByltnvEFSgIfLh/ADRU/dzzu3XwCJ4/7xLmnPil7LZuQ7Bs+YWechpBFBdpYos4Ivv388eexZpJEdYO7psYmLTSjn2y0qyvShidQFZJCGCy3O577IThLbxxWoTX+YxZp+Lm3ZsqZExlG22Qyf8ta2vK7upWkoSUIso0b3q5ZSNO5Hkuyv5O+Ip95SMVVOguLmPBYUeTCEVAc95/K8O5mr8S9VGoe/ncr/HKOabmx8ZhY2kXw6keOyuv3D+G/4ROTMWecE6K1BalDDXkXK+yZiuju9qyv2uC4/t1Dwcw9mdbflBBWn2oQHDr9/7IyzMucCm15dvslau+7n8eS6lNCOnhqueSgZSgkafUJvQQCIOhQ+sZO24zgbD/GCCXoGP3yQGhUlLq+MPCMp3XX/eFlI86aF94b3Qll4mH87bP1NZ4fmfTj/aRZvQonOPcZav1SVk1zO6If7Y6N4YmuxgjbWKdyI7hpNCJkEIV4azinC5002fzATCUdnQRJB3yPmvvsxdEZMhDXFJ8mHm/k7/x/BZSp9iyKYECZL/mTV7yuwikCJOhWYx2XV0yiD0PcSlG4XFpAK3XlJTTZWFKTa6qX5hMlsAYQENBMsgVontJfBmh6IRD5rPJ5LRzTYQYEjRtRZqI73cQlCpBNK/6Ww6+wz+zfwsM3xShbtjjCaFIKvQoRdJ77hE0+R0G+C90sJEWxbTlpEz+oLC/qVms6Fd58536v/f21KgPJCqdoogXraSYxUOiSHX/iHfuCaltLebo+xjXtjetbX8UQowCEEIMx5zoSsB/aU3vKAGOBTJWfScDFwPvCCEeFELk9q5jrP87pex1yYU90xnTS5l9hoRM911oAAMYwAD6CTsQ3F+VkwEURs+8Ojqf20ZyTWvfhQ9sfBh2/ATgHmAHkBRCtAIJYDFOqpKHgCtyD5RSVgFfscqfAWwVQnRhrnb7vVXPh3AC6h8upLk6UfEZFWa0/WOQN4AB7A00RfdPuzLzute58qlVfRfci5BSouvOGP6ftS3ctqsZo8DssLttD5+dPRE39o6/M7lhA0ai/wqDumqgZ7Zg6G19lo22r0DTUqSro/0KwjdVOSvebVJbOp2mo6GORLSr4HHJDU5dVDVasNx/EfalLT+oyelgftNmAhNJRM9YSm0D2ukD2HfYsOFKamr+CxchqZbtCexewGZ/QMoiilVqktSOLs++rq6u3SKAu9HY2MiCBQs826SUPPbYY9nfaj8dxyJoBvWl7h0v2ATyRHf/SON94Xfb6vnfzTV75VwDyOLD8q3vNqSUGvAFoBpTUeYtIUQc07Y/A1QAqzB99B8p7HijTRjafaU2JwjU3RZj06IG6+A+DrQDW9s+0uyrHthd0p6S2my07cj3iwkhiFVsJ13SjJ5Dpk2nvfEOLZAgVr4T6XqY26Z8iViJE8TdfOQMjHicK2SUF08u45hPOQQYWSBAB5AU5rstLjJTHYZCztxLsUgIIqB5frtRVt7OlMMXMfokUxWl5U9/JhRKMf6YNaSOcaVDUwIMHtxIeUU7kyab8081lULTHQJkB/kpO93tcNQoM02qkiW1BQkG+m6bPZppP7dPei67bbk4mTvFVYgS896E0NF9ArhN3V51OiPjJUdpPqmt6mKVHlJbbuD7D+J6AGJFCmqRI9LcpkxAKCaRbzkneQh9uupNaSstAt7m8Y4uha4FSbdNZvwyhyigiwBT2MZv5O/y6tlZWsHLJ1V4tg1S/ZVnbFKYfb+qpTziJrV9hSd9j93JFOYGPsEj4nvM52ymnHE3geLCc1CVIA/xfToZZG4wICAMajMxjpo8genJeZ7yLWNGUGTkpwV7TnyNzUznsdgVLPFyogC4QD7LSdKfbJ8JhXnk1M8gdec9vslnqBaHMJ9zstsq685k5wuOgpqmaNmUe3qJ03aGpM02Wxcex1w+AUAoR5TsXx//GtsnOrohpbFuTt/upJyv7xzMQY791pYfsBB5fwBusrm5vXHweIfUthtMB2mAroR4ruMKGnS35k2+4W8aeaLntyEVhKv/lgXkyHSCHhKPTdipCU4gdlwcaZHhMsKfzHOZvJ2b5BVcJ3+dt++DKLUVQiigEpFOfyhRCAQ0hoys6+UoCLl4mW9zbvbvq4O38J44u9/XDwqVwXRY18ZDarP7adVSgVUVgx76Jsr5YQimL7Gr2Kt++RPxAL/k7+gopEIKYYIe4pLqM3/t3jzJ83s0Ddm/AwUIZbkkQRFMEMI7DpAIIgXUtmx8vrZv15ma8BL/KmRX9m8Fg6Mp7Eu/mIeZKVdmf18nf5X92z3OApPUFsyS2sz77mz3ilBWM5nOUAVXcSeNLoHKbotcPyRgvpcURb5EyjLMxXGlvZDa3DapN5U6P6gixJm849k2uBdiYTzS+7fXG2Gwv/imfCCrkHYUa/sobV83QKGJixSCx/nWbtfjdfFZOoU5vg2gobX1HRv4MLAnT/g1TOtxvmvbnUAXpgGvEULUA42YwWjYvcBzA2bQ+migSEo5BJPgdhrwllXmO8Dfc46ze7W+Ijb2/oK9oBDiB0KI94UQ77e27l1yQ0YUmJQd9MJAAxjAAPYFBshsew9G2nR2adGDnny8r+14M3A58ASwEVOOfRCmJPtm4EHgdCnldy2HeR6klK8CMzEn/dVAEdCJ6Ry40Dr2I7GchjSQQO5CMCkg0U+1oQEM4EBAZ2L/JGl2pzRmr27ou+BeRGPjs7w77whSKfO6125v4I87G7lmW30fR+4htN2z8bqP/TLicaq/fCH1P/u5zxH+UDM6avwVMt29Z5TShkhW7byUTUt+Tes9a/tFCm/urMuOXdyktoeu+iEPXfXDvPJt7e/S1PQSbY+tc+qndfmeuyHWwK0rb8XYj1Qz9iH2tS0/eMnpmOnGJAIFgyI9Q4JSpJADU/IBHBDQezJoHQfIHNBOPxr4AEptagoa1/Rdbh8hbaUSv0WW0HbfOjJ1PUjNoLGxkX/84x+8//4Hi0k+/PDDvP322x6V0ng8zvbtjlpMv+f4dooVTSe+ojnbLrKpm/aSAvm9da080di/FCh7gr/e8lfufrr/6VcPcOxrO75HkFJWY87Hr8fMeCIx5/MrgJ8BJ39UxHQ3bAJNNt0VguZVx5n7jH4otekO4WndvFrmPrLZ2tHHt2OnVH7qG7tZ430H+3vvQ3C339jyzPy8bYorzaSa8bpykjnqzd2D15MsrcMImPMTKXV2jZnFsiFf85RTm5uJWs6Voz89Kbvd8CF+2S6gmEgxefIKRo7aaW53kR8On2YSfgZbOTJz1UUAjjlmDgDBIpMMJYWg1FLPcb95QwTRdbOfDViKb2o6TUaNZcvEfZRjDBSiXV5imU1qUwkRCDptM5n0D0/FrJSOkRGm6JM77VrKMMl8QtF9ldrihpfEVlLh/e1O6VbaOpMxqy5nSs9hHlJbTzw/raoNLVKb/TsjKlEUmM/H+If4Be9a5Cc3JnSaxBFdsVJZBZz6fG7XFxkVlJR0TUW3yFgiqBNA50jW8235z7zzuXHmthRanu6FiQSl6CjsYjIAUigk48Ue4kApPb7HbnQlhLpXXE4wmO+6XMdMfqndyoZNZ7KCE3lLfJonucS8lq4QEAZbe0z/QX3Y204yRWFSIafdHtbpjAFuEDcyp/wsnhPmt/KDBod4dyFPMYVtvnV2Tu50zbbCjVtRsLL+DD5T6pBlasavImPdX0vIUYH6dKNzz3aKRL+g/eLjzgPglDULEUhCGccn8d3Swu3oIMF+bcsPRAib2JS33CzfxmX98rth9uJNEeKlo+kxhjFf/xqZcOGhjMghRRsyQKTY6f/dqX7deJ6L+I54irj13blTjP5T/BTpShvtp7xWTjdjqecwthLIUZ3dm6S2cKIdt9UzUCgqivWpHhdwkdq03VSac6NS684SeCSK079Y6UeBbDrJzaFGojZpeDdxJOsISJW504/P21cnJtBDBZmQYF2wxqP09d6U/PTJsVZviuaAi4Av8FdK0wLed6Z46N8mpCB7z4WgFbfnbTtcbvT8Lu8ZTiLhEL9v4aee+s1gHYfJzb7nLyHuSfU5BGfuJ3I8ZcXECaBb92P+n/s9zOZC5gXPoUWM4n5+lHe9CkyieIawL6nNTter9LLIQXHVa3dIbXFKSSolRHLIhW61vK/Ixzz7XjzmzF7P2RepLfdd5eJG+TM+zavo1rMIoFFkaXf9QN7BzbG/8K2dThv5knwaMMeHue8nWychmKN8AYBZ8oP5LgLohEaP7rvgh4A9IbXNxiSVLbQ3SClbgM8CtUAQc1W2gunI/rGU8rX+nlxK+YaU8jop5VopTVkzKaUupVyE6UB/0Sr6Y3vV996GlPKfUsrjpZTHDx++d2QDbfSV13cAAxjAAHYHtsM7GNx7fUsstgVV7dpr5ztQoESsgXTaXy74IMJs9q0dT0op75BSXiylPFJKOUJKGZJSlkspp0spL5VSLuzHeXZIKX8gpZwspSySUg6XUn5SSvlcX8fuU0gjm7LMAwGJ9ACpbQAfPqSU6LEMdb9aQHLz3gs46r3Ilu9LdLcl2b6if+kl73p3O6tqeo+nrX2njjt/OHePArstra8D0NPjnYQ+WL+vVitZLg6t/31KansnjX9aRnK9t05ap/l8YnPn9lutLZMsfN3Ulq0kVpmr+2SJFVjKmM8lU+MfFLChK2l2xpfw3HPP0dHRgWYFa2xlh1Q8lnfMmjWXsmHjVew46yrnngootf16wa+5f939bOvsw9F/cGA2+86WH9TkdACpW+k1kAQM3XLcGgWdQQM4MPARNqkPFY1/WErTTcs/9OvK3R0XpLphs5WdOBDuvawf3v493HsmtO/Y/WP3EFKXpCzF2hGWTW65YzVdL+8gGjVt0LZte2Zrurq6sn/nKhz1l9RmK7UZuqDz2a003bScTEMsq1hxIH0SmUyGeE+c5k3N/y3k9Nnswzl5b7B87kIWkhhxyvVIKX8npTxKSlkmpaywfOW3SCn3i4lvrlKbRCEVM5U4+pN+1JtCU/r+mYUnT9meqzH0FztWtbB+Xu+qKQCGblZa6UOprVSBQYH+MADMMm1t71BT+5C5xfUMNNX0m51//vlAPqnNEOb+QLib0Sc+iKHNIdP9cH7IdruTwVZ3PdbOYSvQgo4imnBdv0ckGTfeOy9TFA1Fcd55IKBhINg8eHIvoztzj6EohCPmPEl3BVZ1lCyxImApv6npNF0Zp14PivxFOQYBtmw53bPNJqV1MoRIxJmTFSK1aZqXDD5q6XXZv1UlwHJOQgQ0dJ+2GJOlbFrrqOeMm+6NbaUooqVlEgDh+GjKW49jamoiXaFyLhbPsYEZpLTCZPSAq48uio+hTB2ZTW/ZgpfMd9mwFP87czmBiI4e8EsZKuisCLGpwkx7B6aqjR1Yn86GgvUAUDVJLOifpjNOCc/wDd4VDtFODUYoxmmruQowo9//FZE1X6TTR4EvF/fyU+pC41hbeQTP8VWAbL2N+mICQiIMhX+MT5CZnl/HjNLNYNnOlfImIlphMsOgRJfnd2vVhF7rFVcckol9r0mKkalKhm37EnrsUKLCGWdkgiFCReb32hQclN1eqjlfjk1ysf+/WP4ru08pMd/rSVtNVZlBW1dn940Y65zvIMVsPiJbfrDCno/n9ttO+lGnz6u14uwV42NcMSJFxCcNaS46t5UhLWL6zqGtRIesQ2LQUxn0uarXv6Wny1gfOJJ2q38Yf4K/bbZTHNqpONW8dKTOvMgvzXDQlbEhmJOtNt2P9KO99SduDC0d7vF/GCgcNnVxn+lH3SSjXMWx/uJT8hWmqVuzRCCNMNL6W3cptWmW3RABg24q/E/WBwbRhS4Kk++kRZ/ShOJJPwpQrHnbhMj9jfQo9gV85jCpoFchTmDQyRAAPlMXt+qg9KnUdtrQe/O2nR5d4vkdMpzxCkAJ+QkNf8UN/F3mk8xKXEQ1gNKYMz65yFI1vVA+yaFyC4exDft7seudS0QtIkm3Yr4zd6pVG2XW95Uh4kuO3F3fnF9GJT8YCJZyCgCVdHKY3MwMdSt/lz/KEu3Ol8/yRV7Yreu7yeMjZH4a06I+3q83Tb1JJrPvaBYrGa9s51NNzrudwC7rfpzxUy66XeqE7ut/Ur7Sa13cqH5jfM586aPDB559WcHqh6WUL+VsXwxMAc7ElCD/HDBWSpn/tX3waxuYK8LAvIfPu3bbVqavhPP2/t6jLvsI2oc48R3AAAZw8GNfkNqWLjuP5e9f0HfBgwzCIrUZqb2T7m1/xUdpxw8KSMNnTQ0gIK1mUPX9Y6A3gH0PNZVC62d6qN1FfwPzz9+8gvuumo/aYE6EYwu9ymFV0Sq+9NKX6Ep17XYdVH3fRUINKYmq/n3tHbet4A9zt/GPqiau2WY6iRbVLyKj5ztLbnptCxfc5Z9+w8biF8xVz6pFWN68aD51mws7x9uT7Rz18FH8e+u/s9uCQXMirmn+qU0+CGb/9UZu+ernsgQxX+x6r9/ny+yyHAJ1MdKJBAufeRxD19E7HdJf7L3+nS/e5X+f6Z1VVH3xi+z6+jdIh8PZQKId5NN7zHekRdNkGlwEtWw5s39sbGzktttuy+7ufr9vrrIedqZuquZPaoumze1JLd9xc7BhX9ryg56cDhhSz6YfDRgGKiGk5QT/byFGHYzY26/uo2gLDz30EE8//fQHOnZeRw8bYx+8/7v41Yv57cLfFtyf2R2F8IW3wp/Hw3t/M39/kPSjbRZprGXT7h+7h+h6aTvijrWEgSZX4CZT20M4bAaicolo/UVJiemS7I3Ulkj08z3aCj2uMVtqq2P3P8w2rBqSB+ta0VyLCJLJOlpa+he7tbNkSKTvmO9gw8CcfO/AsMaYdoDVQGDotlJhP0htuntBo2se39e3o7jIOfs40PPaveuZ9+TWgvullLTW9GS/90Jhh0xK459XzuMTFSHOKg9SUuklGxt5C4DM57hm7ffYtu1GGv+8DLV7FSee9G+CwVSW1BYIBFAUhUTO4hlpKdyMP/FRKictpnj4evM67kLBIhJvOCRt9+ywsrKZQz59LSKQZnBAEBKS58NLqVHa6BFeezRhwjpOO/1Jmk/TuYMrzesEMqyYdDgvTvwUqziOKibnEQskksbBAfRAwEWoct5thlA2falbqa0l3bs9TBPBMLwvwrDOu56ZDB++K7tduEgYDfWulJCaaTebGMWbbT9GJidm991ZdBX/EL+gOxzCEIIvyue4Xv6CH0pzfhWjNKswB9CwZR0v80VX/YqIxcyAeihpk9AEDeUm+e0/fJFXiz5b8P4Ekmvl1daNlRJQNIJWCrAWRtHlUtOZXmw+11HHtdIxyEuuixulPHXCx7n15OP55imlRLtGAVaKVqs1jCQ/MOxGoJfPbx2zPIprAKmgV6mthLhnf3dyOpOaL0BL9U0csYPw/xl7Lg3CVO/JnjsEqZIyAnHzPiZMXJd3vBoMcTQrOYGlKL2QucOpXZ7fIS1/IXbQlYZcDzpt2A5iv8eZqN0zGVr1Bc7+RAVXHe+QQ9RAAGERR9oUM11oqaYTclXJJuGohJglV3AeL2f3rRxmtrVBgZFm/XSn7w2N6CtMe2BjwJbvfTicIvOPQw9dwpAhdY6Nc/njZ5eZhI3ioWkOiRicVOr1MZ71V29qQRtSKGTCXdnfejBhXTvnOxSOXWtsPJR5wVP5W+hXXCF6V5DMhZvEBqYyVbHlS074qH2GFWcc7CYZQf+U2krJXyzqh2BIeJSuDBQCAb1X9bURsslDXgrTf5/4CU1OOsVZrKS4uNshtYlANi1ljxLP9qV2CtBwcfwDK7Up9C5eYaAwd9px3H/mFzBy1E/PbvG2qUAeqc3bZvxSkDYnjiCddvpCBYMv8zRf6Z7PxxvMOV88WFxQqe0W+RMel19mMjvz9h2Z8s6TQxoEg9551F/kldnxAZh2YQT5C8lLSBB0PatyzbElpzOfx+WXuYB/83t+g4KRJSEWkc6OWdyIkKJbFCYillv0nELpR3tTaPNDf5XanuXrPCBMUt+JLOY6rua36b8zghZKrTHBB0kleoO4Mfv3FdyStz83fXcu7HbqKLXp2P1gAJ3StplUZsx7/OLOFirosuoaIFzUN9XJTWrri2DnRs+QI/IWrnxU2CfMKktR7T0p5ZNSylellHsv8uNcYztgSxAc4tpl5yEaLITobeRpJ/D9cPMWWdB8ZKFhIPvoAAYwgA+GvUVqq62tpb3dkbFNJmv26HwHIuyJ03+BUltBfBh2/ICHYQAib6IiBYSkpDNx8AdhBmDitm9dyL/+L391096AofVvZNi4PYqaKtxn2apV79T6O3N6g5bbxqXktpW3sal9z4PLf61q4vD31tPlIrZVJ9NkDIM7ziplzvGl/Lm6ifvr2nirZgGXvXUZj2z0psLU+kkg1TJmuYxFWH7l1pt4+ne/LFi+tsdMp/LCNmdVVn9JbbsTPN7xvrmibtfXfdIW2QZp44vQ3WhdO0Y63Vz42pq1cjUoWPDkwyx57km2LF7gIbW9vKt/Sm3xLoc05g5wxd9bAED9mDHM/tIFdA4ZZBUy/9Nj5iS96U/LaLnNIesFQ+b8x15dG4t5nWzzl1Zn/7792xeh9hEoUgsote3qNh3+d66+s9fjD3YM2PK+YRjSQ2rTCGZJl2ltgJx+QMG1zsDYywsLNm3+NW/PnbJXz9kXdu3axaZNm6jb0snqt/LnY73Zma+u2cHHlm/5wNde27qW2dtns6jBnyyeSfbPhgDw5rXe38HdTD+ajsH2N82/o7W9l90HiK8w7e1cKpjsIjjgUkBypw/dHRQXm+7K7m6na85VZquv62d6c3uspjv1MuKqk350Dx2Nq7sTNKUdB/zlGwq3r4fqW/nNtnoebnAUY5e//yXWrf9Jv8ZHzc3mMy8lTKKu64NX+iDAgB3ffWRTHyHQre+hP0ptumaWUQIBcJFK+myybuaYsXcXRb7RFqWzwOIfP6x7t45n/ric2k2mYnchpbau5oRn3lg53AmdpDr/xqb5T3jKSyHo7FwGwCaOoDaVoXzMbCKRJIMHN2ZJba/cehOKMJXaUsGQE98QBpFIjNKRZporrbQUETAgkGLtUTN5+mtfJfOFk4gWO2Qr911PPuR9Skq6mTq8iTPLg5xZadChxHgvtIl4DqmtuNgM5j2nfI3Fwszw1xnsYsXEaVb9j+QacTOv4yVqLSs6mfs/WcnyaTOyaUrdSm1BMgQUs1a28snyjg7uWd97H60S8qTyNO/N/B3Hq9gS7RpJy86TWbzoKyQSldnt3VYbuIlr+Nfwj9MZdt7rtoB5X9FICENRCKAyhR2cbIlFZWQlmivStH3rWp4Sl2R/p4nQUD+N4Zu/zqC6s7PbFeuQteJY3ipylN5yIYTBYCtFl64oKAEtS0JbKk7lJ+IBDM3roy4tKeb1s53F0231o3hxw2V0lThKMBs3nkU8XolGMEvkCNH7t9CbMssmMYOdOUmekoEiTzA3l9TWUKyQRiVD3wqzGSN/bJMlJYQknUackkbn/EM2r2aaZoYlV0yYSry0Ipv6rIDICkE1Q3kyys/ljfxBmjofQZnv/y9xzZ+lpV4Vj1dmFV8SoozvjLwy2yrWDnHqngpFWJCjqHbVjnZCrmdrEw5iqcosgfE38ncM7nJsfplFXghqrnf2X6ztMWDLPxhiVrvbzlRqAuMZPWYbU2YsoqHCJH+5FUNzudgTwt4PaVe7/9xFIkiUOvOLWHmVde7cjCwOyUgAzcrupdO1yV+5JDFNhCi2yKl+Sm1uIlvwA5Daioz+LbwxAmkPKctRTSscY/x8jnpVLqmrN0jX81UwKC6J+pKHAsLIJ90oMs9+9hd9kaN0AmwfOd6qo3cMFcw5NGB49xt6kK1bT3VV07xHN9H49Wkns2XnSa76SCawi08sTzDGiiFFIxUFSW3DNn67YN1zRZeFbmTHK0UtRwMwjlrOYF7Bc9gIYHhSywaln7qq61rWc42Q5v3l5+ftLyJFDH81WnDIlxnCxHzerfu9BfwTROTUp38T3wWcnf3bHrvoRV2AqS4H/mmB3ahIxnvd70dgyyWoFtpvp+Q1ldoscu+CP1Cx4SJGpiWvvhvj/J1t2faiC6/K5O/lr3zP725f4X4qLAppYKhKdlHeR42DcUix3vX3jIKlnH296xfvI2i+UsuwW8m/BzCAvQUtDYm9l6rsw4SUkuSm9rx0YvFlTdT9agFGMt/YpbZ10vboxoNKgcFmSreVD6I+9cHJNA888AC33347Uu5dQlfP/Doyjb0b+v0F0iKRlBwzoo+SA/ivhpQYCALSYNH0Ur4pHzQ3AwEglRkIhh+okIaBsZuqG9Hm3lcOf1Cou0muLWTXRD/Glxs3buS6665j5cqV3jrkKLWl9BT3rbuPb732rd2qmx9eaTVJSY1plRtuuIEHZr/EyUs2cfzijRg5gZjfVFur4nXvpDDVD+LJM2+9mv07nTMueO2f66nfUjh16dq2tdT1mEpxgYDpOFLVaK9jCH1vkWHcK7VbzCnL+ysu5L2Fp/Lq7Tf7H2KT2kIKdR1dGMEweiaN1u6M855essv32Fwku23SWdBDErFTmbaMMO1k9xBr1Z31SDJVUXrm55MPAhapTQv5jwcM4TjNMskk3W2tvdYvk+nAkJKUq26tiVY0qTE8Oobid0bQ2TzgMx5AYRi6liW1KbZSm52C6iCaJxys6Gio463778QwdIrLnaCjsYcKo92tLR7iVmPjs3t0Pj/0dx764t9XsfDf29HVHIK5a3ygdZrO/taMylWb93xB0qigAUgue/MytnTkk5cyyQTJMZNJjD+04Dlaa3po2hkFJScYUjRo9ypTt8z5O9a/lOS9Qe/OkFjn2JaUblCVcMZ8anMLuks5jQKLC4Qi0C1lpw+q1BYKmYGtnp4eduy4mWXLv5h3rvmP3devc0mL9CBdQQe9J5Pl2+wp0fPTK7byseWbs7+fbSm8SrvTIrh0WHVqbX0TVTUXzRmu4Nr2zu1oOSSgeR09fKNLkgqGGKJXEH37fc8xAxhAIdixxUCW1KZgixj1pw1p6TSBYJBAMIQ9oJVS+rPa3NuEW6ltz0ht6aTG8leqMAxJe0bjknVVfHd9Vb+Pb21az6FfuIpou7l2XxQgtdnjcRuGNXewbWd741w2vXNddr8+aDkrV30dgBvFDZx/ZimoJqkgHEmgZmx7JJGpFN2G5F+nfZblk6Znz3HMMc5cTJYVccQ3tjP9K1ez6cjpBAIZ2j7xJlVn/CJbJmkFgYuKuglYCmlDwuYcULNYPyNGb2birBf7fC5G0HkOqznOvEfDm1KyPmgqg62dPiNLZrDJZ0GpkxJFWaU2W8Hnd2OP4D/BQ+gNC8VZJBUv8cAmy6WJeMKuD4/8Oi+KC9C0iIdQoeumrbDJVTUl+aG8W6ebaTWDLgJYWKYJGMPRNGd89PTEb3uOS1OElAGG1HwK4bIfbx1xQt41PiNfztumKDohKzg6e/RnCQQ0RI6yWW72u5IpXm0JXRTlLRQ1jBCdnWM86UcB/iov56yapXn1AFA0//nlCd3+otKGCHjIEkF0xhsOSbErJHm0aD7JgJew1sSovHNpIj/GZ9dbiwQwhERxMSLGnlFD6aFmut3lk830hDahQy/2J5GMaG9EaDCLVUzC7Bcywfy2UKw6D7xr8MdoYSQ7Wo/OI6fEfcKS20aMy9sW1kIEXfGWpsyhdDKIjIyQaTaJgkeynq+/6IxXwoExAB7VuXh8/1B3GcCBg5TVD+4Uh/LXQaZ9uI2fce3nPoEmQLjbdA6hZ2Qof9yrjjZouCuDeqzjT5QigJDOd6RGOikra6ei0jvnUILOYkyByJJEob9KTlbKbB/CTqk1Xk76pR919X+2epmNQmSbCbLaOb4fBCAAI5D0EIfse+qNOJdLhrFTEvfneUyMO3ZAYFBaEs2qmLpxeeSmPILX6HFbUQmj9BG3dKt1/WRrms+sW5QlDxeCu5/MS+kt4P3Xezii3lJJ01o848FUopzuqKlSWWEUZ+37kLjjj0yHwmyocJRYbaJSizaKeZhqtTPqtpOqn+pbP6kVJoYl4oM8vw3XN5FO7r5vxCYtXyCfyS5KLgQlS2pLoqpFVEpvWw6i9dqWyixS2+t8liqR719wk9TCBQh/69Y66cXtd3907ba8ciNlY/ZvN7nMJs5nOszxrT0+SPZBaju+ejNXJW/mm/IB3/1BH1Kbndq0EJz0ow6pzSYZZuKS+dseZUXbG4xISwIIhqUdX7/7WR1K/v2D1zbb3/HIdAs/XOcsarlS3uQ55jEuQqZ1D5n4o8QHJrUJIaqFEA8KIS4RQozfm5Xq5/WnADYt2j3Lew+ySYI/XeDYiYA9u3pjn1SwD9gD3o/L1/m0/I+zY8B3ftAhubGdul8tQI/vm9RkewWzfww3TQbtwFMWSqxsof3hjcSXeQkFsUXmZNR28rvR9vBGUhvakT6Et/0J6+ujRJNmu6ntSPCTJ1aSyPjX2V7V/a+px3Pc4o3MufNvPH71/7L8pefQPsDqcV3vv/xozaXfY9e3vwNAuqoKtdmrIGOkNKKvVtFy60q/wz9UdHQsyq4ytZGp7aHuVwvQ2kzTYRMCIocM+rCr96Hio7bjBzqkYViBcBgSDmYHmFIIyggNBMMPYLTc9Fe2HD0Lqe0lG/Hsd+Ddv3ygQ50gQf+QbvJ35irWhNwokM7ivace4ZlnngHgpZdeQnc5LrUccoCd0lF1pfLp0XR+u62OxG4ETe+tbWFrwrQ1UU1H13XeqTftR4uPravRzdQog40i9IRKiQETVIWU2vsz0g2dF5e/RriinqHTXyGT9JbfsbKF/9yxxrNt9t9X0vh+CiElg3skV75zJQCGkbH+T5HIcb6v7nYIENreIrW6owCq+azicXNiuum9d5G5kvZaBtlspllNyQzV8TTJCYfR9JtrSCx3UvoEDR1VN9jVvYtVbzxO6y6TtNCWbPOk+lr9tjUJFiGPaqARs9qZnXLJXnDqqk7PW/kT6GAogBrsoWfQ5rx95vm8U1O9j7S+0WQDv9pax6T5a7MEkfaUGTif2DqIiTvX0FrdPwLfgYoBW75nyKRVy5YbllJbCHm4OTfX89JvDWBvYUU0zqh3VrOqezcUv3zw7A1Xs+bNOfS0taGm9awqjZvUdn9dazaFdX9x30+/y5O//Xne9r25IEr2ohwUbc1/Lu3uVM6AkXDsZNNfzP79LzubeLJxzxaqdXQu5lejU5xcahGTUvnnq9+yEa1yKHrZIAzD3wY/88flPHfTCgjnpNKJ9G9lfToRN22cK5i8KbqTox4+ipXN/Z9TdjU1svr1V7K/2x5aT8fjmzGs8dVPNu3ilKWbSBsGTdffwPazzmL7xz9R6HQOXKS2jo4OpJTEV7WQ3Fz4+Wca4+jdjo1NJ82/qzc1Ur3rbnp61tNT1e45Rgb7VogBkBYBJLlidXZbcvWO7JKG/ir/+tbbGmt05Iy3EmqCDRs2cN111xGNOs55m0djSPObWbvuh9l9um627Xm187jgpQt4ZdNT6BaB1Ein+cH6KrpEgK6SMgik2Dn5/7F5c+FUuAcDBuz43oFhtXZbqe1tziWlWwrB/Ug/qqbThCJFplJbltSGv4/ePZ9yB3f6cZ3esPDf21j2chXVa9rIWNfYmdgNUmfZiwSLYsTT75lVK0Bqy10QbKct1q1+ccpna2iQj2Z3a1Of8hQ3hEAGzXlJKJjOKrUJKSmSOomwGbjcOWxM9phQ2LkPJWAQKtGpZyyZQDCbztMIOj7I+9c/DMAJJ75ISanZv2hBcw6aLK1l6tSFjJ+6kPJBjVRxCNVMLvhYDBfvwU4NmZBeW2S3m2hlRVYqyyafVRgJUqKYqrLxPMElKIq5P17UP7WK9w452vPbDlLqIugJoG8tPZR3DzGDuTZxrq5uelbprRwzMF5TWjiU5yZAlBCnPjwUXQ+hEiRGGasqvGQ1vyBzMugvwuAXSFYCmiflnFB0UmkvYVDq3nZo5Cy20wljiNwykE6XoBPwBITH0MCsyHJyMXXHemTyfd96H1633nc75CuozNQ3Zv/uCZhtIiW8pLb/E3fyBN/03kMugR+HhBgZ3sMRpzYzZHpXdt+g6VFKJixnzJhN2eC7XT4aGJ53LoCKWBSpmc9J1wLEN5yKTJrHjOlsZbBFnAi7VIEeHT+Dq8Rd/G38j/NIbbFQfv+wowCpbUvQWQywJTKRn4oH0EUQkXS+o1KXWk2pj7rTsxue872vgwUDtnzvw099cT1HAWYfMbzIaa+5Zi0i89t32+EmOcU4Q0VXFLZPmWL2PTnE92OOfZWjjnrbs23KuQ7ZQyA817O/rbhP+lAbD3AZGkHWcGzevhK1sFJbU91hedtspPFXvz7OIkedJ18k1A+lWgA9FGcozhzEQGENs/iLuLbgMSEyuMV5VELU1R7BvPf+p9drRYwUpSVd2d+2UttkucNTboKsYijteSqaOgoqwT5TOAZcc9QKVTKxo4UF83uvm7ufzBUkskd+Z2xfy2XzZiMR/M+S1zl942rASyYaLEuzdi2ieev5n3GO+ql9vZ5IE0JILps3m9/edxsVG7/gWz9dFlY8r6+f5vkdD0Bjo9l++iIA3SJ/wnUtf+eh5S3cIS8FHGJVCBWU3n3udupamzRo5AyeVUKkeyG12UptjWKs73434bJQusyoRSgEp+/ITed9QU2CY3HGCl4lRNN2bnrZtMHTMMcDx2iF/Q4Xv/YrprbUMl3fyAj8s6mEcoiUP5B38DUe5WPyDYoz5r18av1SztriZDixx6R2+wiicS2/5eQV7/D2rnspizWyvWeVVVawfuUnEVLnWOmMj74vC2ctcasq2t+RgYKuukidPiRTI73/iHfsiVLbBOBbwENAtRBiuxDiPiHEN4QQo/ekUqIPyp+1/6/WTwPIssKklHHAHin9SIgcGrMJO9dQDzB7T+r6QaFZQaCP8Qbf5KHs9gHX+cGHngUmuUotEGjeL1C9AAOBUWDFU7eme1Yw9watsxO1vp9pMvYCjJhpHLT2nFU/AbN7a7ltFdvmrOapp57ijjvuYPv27ShFlhOhZy+T+Jo3wHWDoLMaXvgRPP3Nvo7whSENNN3gc7e/x6X/Mg3S39/ayitrG3l1nb8aUCLhDX5snD+Xpu1bmf/4Qyx7MV9dQEqZHwx318EoTGrTXKN3KSWZOoXkSlNBZudnzmP7WWd7yjf8fnHBc+0LvHX/nbzwl98DoEfTnve8avU3Wbnq67S2trJ582aklCTWmhP0xJpWOp7daqaZUUAE9g/2+T7EPrPj/w0wA5sCIUERgewERgjJZwPTB0htBzA6/vUvAIyUv91zB7WN/pAeNjwP7/6x13NpnSk6ntqMdCmxpOIqL926un+VBoYFBbE51b77bFKbLDDSXPrCM57fHc9s4QHLKaPn2IqEatobgcyqet5T28J9dW08XN9Gf6BLye+2O6vzWi0SW7S4sCMI4LPLDE56ciiN1y/hK7EIX41HSKQcx+1xN7zJTx73Tjpbk2YfP+kTf2T4UbNJJeN59s+trKarBvVbutj5UoILFknuvUOnrM0KuFqEb91I0ZUT3N0Qc8YhH4TUFhh/iqkw6yYyamkIW85iLccuC4mmqV6SxaLbkDvmm3WUpivBCIZIREJkduyAclNRLWRo9KQ0PvfC5yi64kaqvng+KS3Fuc+ey8WvXgxAw7btdDaa71OIELqLsGjEYkSOOo/whNMAUEeYzgfpqnsg4AS47eCZEhB0D/aKZEtgw+hJqEoAQ1E8LTSTSLCqZRV/WeYlhQ7d8Xki3RNQtSiPNJjONzteH8uYDpExlrx9pKz3lXUHAQZs+R5ATWUwUFCQKNJAE066rF6GyQPYQ7zZbgbe5rbvmZJirMNSf9J1tLROpDRo/XZ6kmu21XN/Xf9skxtttfmEWCn33txR+qycb0mr/O+6XTz8uyXZbSWVVpCz1bQx3W/tovn2VdRW76JNOM9Pqr032K6WRL/GLN3dZh892lI4yFXS6mjo5M1/3pH93Rf5OGvDbPRDySgZ6+GO73yVJc8/7VF6W5o0xw27k0r96et/zdsP3o2aMcd0WrtpSxOrW4gtaeC1NossISWdT5gBKyPet99GKALNtfghkUjQ+fQW2v/l2Lj75u9k4fY2tr3fzMaFDbTcupLGm5zFVamkWSdDOOOWzoVmu+swrMBb0JumKBdVibQ557DqEpp8VnbfqspymmMmyU7XDDYvbuSBny3o39jVhWVR/+dx3HPf5MWNy9g6Ylw2ZagbBs5iABu6brbjN3a9QZGQlDX/jvd/ezSPbXyMTaeeQk/GcqwLBWERWDo63tut+h6AGLDjewH2HMcOwq0Vx7J4shk89utvc6GmUwQjEYSiYIcupSH9nfRuMq/iCvroe7Ygyk4JqmtGVmV7t77WHPdVIVKbrkokkvuL3ubFygYWDTfLxS3SbaCoH4uqgubcqLikm0zGGfPXNPZk/+4qLWfLyHxuhxIwE2L+QtzGK0edQiCQf703tr2MyLG5y0rNAF73sXczctTO7PZrxF+5WvgrWDfUH47mQzjqwEu8sgOfEoFiqQPZAb0Ka/73yLiv8or44m4n2NGEGci9m8t5jos8gUK/IO8jJ3+ajpgZnO3qHI1hmPN4W8mkrqRwBdwB2jJ62FI5hrQe5iau4TLxcF55lXwbU1fuP3fyS4cWUHRPwNYIQSInJabMCT3mEjF0PYga8B6jBkLoWtiTfjQWGwzAmBHbPWWHxKJ8/q1nKClz5uLDZTN/kz/mopoM43oKpy4P5KQ0nWw4iyC6LbJlxoc48oo4v+A5s/fgSls6cnKMMSeaPok/cS0vYqZfnXLo+9kUd/ZzUYW/3T86NI1gsUkU1dIh5LZZTGpv4pMblvK5tYsYbaX/DOr535MaDOWlPfzPmN7HF0I648Cqkvy+TQsECOqSnXNuYOPjUzz7Siwi5tCIQ2wtSuzZQpYDAAO2fC/Dr6ezvUWGgEllR3rKbmEa/8FMY12Zzidk2EQXQxdsmj6DFSccz64JQzG0KsrK+z9XFOBJHmgTT/7AdQWP2SyOZAXH+6o+lVhj+IQPKS4dK6zMZZ/rx/Ifnu22ilwIjWL6p5Aog2l+xh/4mnwEgPvFj7lJ9L6oJITqGaNohKiqOg7dR7nSc5xQGTfSWeSqoBMKZfha5nG+vOIdSqwFMC2WKqZNeLJhJsYM+SpgueFWAHXq2bsB34mjEvby0ad79tnnEPZZhKAsk2Jw2668Mys4fs1cUpsbdttJFrU75zYk5XqQ+xPf4jDpXQy8OrUo7xx/W7iN595tJZfmEw8VsX3bySaRT/H3E4xeay48GkUTgVUtHNVRzGC6rLo4pDZZKC+2hWw8zDrGyEnfqxLuldQWJk1ImmOMcpmvYuYmteWORU6QSzixowXpUly0L69IyYWbdzAuYR5fbAQ9KovNrq7ZJrUZqtl+R9PIY/LLTIt7xxxuTJ7ZxRlnPkppadRD8Pfem3f7LFZSRJpLuZew1TbK0glGR50+yCaanW9RnMZSxwR2ccbyt632Z95PbXwLHelmVLWYR/gq/8efs+2wtxSnAeFSqLPG2rpQMFRnXOAeHz4mvwyA2E3RhX2JPSG1fQN4ANiJ+c0dAlwKPArUCSE2CSHuEkJcJITwX2ZQGBOFEMuEEJcJIQ6xSW5CCEUIcTIwB6wRINwrpczNiXAtEAdGAy8LIQ6zji8VQlwL2EsFb5RSFs43tA9hk9ryWcUHPYnivxBOR15bW0tLy56nzdjrGDKFMWe9y5frA2zZsoV4jiP3iyu3ccrSTf061Y5zP9m/1c17AUZCxbAcP7bKlo1Uwhn0PL50Nps3b6atrY2tW7eiFAdpUDq567H7yPSiYrZrQzubFjUU3J+HVY8DEh78NKx5Aja9BN2NkI71eagbJz1+Ep969nwAVtd2QfsOSkNmn3H73G0s2eldwa2qKvPnzy94vp7ODv5a1cj2hBMQf/w3/8vfv3G+p5yUOiNG7kBRVO6//27fc3WqGuPmreH+OnNCrnelKTrmm5ScfbVZIFRKYNRMp26ZdEFPnJSSdevWeQICGzf9ih07bqajo4Pq6uq8Y1JbO2m65f2smpof1rw5h50rTTJg45+W0fiHpcSWN7F27dpsmTvvvJOnnnqKRx99lICVrihdHSWxohm9I0UfyroHC/alHT/4IXUMBEJKhBLMTlmkEISV/JViA9hP0bAKVj7iu0um/B0AbgLUilf6SHmS7H2Y+c053+SCFy+g68UdJFa3ktrmlN/+fjNdzQmLhNy3M2K4K7UKEtKazl9f3+xR+DSkQcYwGPXOam6uKpwyNb26lcMth3tu+tGEZjoZ/jq2h7nvTKWl5bVs4OWFlk4P8dkPVYk0b7Z5iQxttuR+qPDKM4BvvW0QCpgO7eGWg/8fr2/N7m+PZ3hlXaPnmKZ4EwJQgqa9Tydi2eC2DUPCq3Xt6FLS0+E862N2mO96YsoMytsKI3V1j/Dm+j94zhF0rcnRXIQ3vZ/qdUXTTQdcx18fhvXPmxvVBJRYQRc1SUvr69nyU79UxcmPnMDMR2ayq9siX8TbQJo27XNqlGeO/xgA20YNoamjjkZLsSJo6HQnVZCSzESDkpDkN+/9Bk1qbO7YTGdTA09ecyVa4i0ApDSo27ie1vvXmcS7eJzqw05ifZEZxDaKzfcmM/bUMoN0rY6VqkEylqGnPeVJ7wBQM2QkC6bOYukhR3LHBZcx97TzsvtSiTiXzLmExzY95jlGUcsIqGWoald2m2o5Ke32WWalTpXFezLdPSAwYMv3AJqmZ9OPBnQ73ZTpXNQHyOkHDFJxc45jpyCNR/deusJ43Amc5xJ09gSGD7nrN9vqeKKtk+2jHCdipMRKUdmRYv1bNXS/VUOmvoeHX3qS2ZHlqJbDUu9Osz7mP1aItiZ4/NolPPyrhSx/xT+VndQNpG6QUk37nLaaf1LXPd/C49e+5jmusb6e1atXF75Ri9QWbw4Ta4h4ySAF0HHH5wDYMe8ljGSStsx1qMYYhEVa1vtIN+NGJmH6NTrq61j87yezHtCu57fTNXuHLVDkO3ZRm3sht7mU2gDSPd5nL6XkD69u4uL7l/L6/et5/Slr8aDNwG5cg2ap5GvF3bzM+RgItlUGePe4IxgVH4eSjCF7IbVti6c4Zekm/l7dnE0/Ghp/cnb/90+u4NrTh5nBN83g3ce3kIqpfaZIb9nVTcalaH/h6h2+5TpH/pbbhh3D3OnHs7ItRVtnirpUhg1bzXutTaQxcsavupEgFotBDMoDlsLqaQFef/w+HvjEFzAsVYTDj57HpFMtAsZ+kuZkH2LAju8F2MNOdxAnGTIDaLIffYaaShGKFCEUBUOtRk28a5Ha/NKPur8ht1LbByO1adE0db9aQHnMsTGadd3dGYnkfikFOG3ouoEUZl1vOPlwnjgshJSSlupu3/MAzOUTvMFnsr+lRfgZNqyWaI+pbGoAVVMO5+zzvpgt98604/LONWX66qwqVXPlUBQl/7l9PlzKqLB3Xjh9+gKMQApZ1OV/Y5ikhjvTV2V/a1o4ey03ctO2KVbAtri0O6uSZiu1DdK9/txXlc/xYk6wuzdELGWV98TZPC++5gma+yntJCJFNGYmsGjhV+nsHIttuOygcXewcJ/oVmo7nXkAqETYKI7yLX8rP6ejxCFNrEvo1JT7LzLLTTUHdvpRJ66VEWESuSpdOdXNTbEXpRIth9TWWVqOYQSy6UcNQ6GhwUzZlqt68sWVC1CkweAJTiD8SNYykmb+b0OMYC/q+7lB3zO0ZXxx9QIAmgPmGCBXrcdGruJcLvzaHcB6cTTPiHy1ILu8NV1HySGnDc4YdJXY70YS1i2D0dZo+iItWzko0YMf7PnND6S5MOGew5y2d9LODXnlbWU+RRq+pIxUOEJAz5DqVMjEvPdaKkIEi07hrFFfy24rat891eQDEAO2fC9D+Nhfux/UBHRmml3b4XrxB54UlwCmImjesdZYP1Y6ml2HnsWkySvoGjqSSdM3ccwxcyhxqYf1BgUnbSQ439Yu0Xs6aomStStuFFkLhBLCp+91KV1+Uz7o2bVFmKmLc7kFdn0CaFRGvPHD3jCYLs6k/wuHcm1CA2OZd9jRLDx0ZoEjTCgYHIGjoGkvRhCawvBYlETAtBEpYdrpUryEWAMFjWA2XWQu7JSTbqU2t3Dfqa2FbcJ94icF9+WL/1kKwTZ5ztVeAyhZwnJYLew/sMnGhu5SiAsFKTKCCCEpcd37mK5WMPLt0YikziAr3Du+w/kmYkX2OEcUVFrb2uUsrJKqd85mx7gUDIq78lOCupEls1njlWLptQntDCMmChM0Q2gMxoyF+CmxCQ+pzbv/Sv7KFdvWebbZb0IxJCc3tPL5evMbiejSN80tmPeZaPN+wwLYvu1ENC3EGTL/2xg/2GlLuWMTG63LL/L8tr/Xjo4xWfJdwDCoTMaZWbedU7esotJKT3os73Pt5ltItg3x1stqc4taZrMjtsaqv724R7P+Lzz3cZMEE51mvEEXAQzNn9SmW9uD+v6TRvwDe/mllE9JKX8gpTwMmAh8G3gEqMN854djkseeApqEEOuEELfuxiVOAO4BdgBJIUQrkAAWA5+yyjwEXOFTtyrgK1b5M4CtQoguIAr83qrfQzhqbx86NMVhTYOzAmJAq+3gQXx5E5l6V851AQ888AB33XVXn8c2bN3ExgXvkK6O0nr/OuRupPP6QCg2A8SLtRKefPJJnnrKKy+/yQoU9BWoBlO9Y19idXcim66m8U/L6HnHXHWV2tSRVQKp27yB9oYa3+NVVUUUBVka3EZnTxdtbYVXY/zn9jXMfaRAiiw/2BPxHldA/W/T4MFP+ZcvgJSeoiVtBhwOlzvh9mMJvX8vALvaE3ztn0u85VO9pwrtzKjcUt3Mhasch3Tzzm3IHBnWaHQNhx++iGOOmUNPj//AtzNmTmxv2Gqq8RlWWl2lxDSwJaf8lJKTf4phKee013rfg1tRZseOHTz33HO8/fbbrGheQWeqk8bGZ6nedTfvvPMOL7zwQrbsmh7zvc99ZSNaaxKtKz9YdcoTp/DL+b/M2w6wZPa7PP/883nbd+7cmfX2qU0H/coxDz4EO35wQ8rsqlMhgs4gW4CqpPdqiqoB7EP882x46XLfXYWU2nRLDcXQWpn/2P29nj6+/YVe969pXcP2ru0Y9kTYFX2wA9laahHp6N0kY/kOyqoLL6L5r+ZwNuIK+qW3d7Hw35uoeKee+17b6ii1SUnSGlPcW1uYZK+5JkCaj1JbkWvlVVXVbZRY6qhre5KMm7em1zSkpyzdxLfXe4Pqv95aRzIUJh7ZHVUtsw5vrOmdfF4V9V5rw7wnePw3/+vZtnF8mO9uq+XqDUv5wePfB0AoKkODZTz9qc8j2qfy3o73iCZdqTe6Wz3naO7pYesSU03EDgoBvNUc5Z6avhc0SGtukOo5jNTT/4BYC3TVQukws4CWork5K05NybA0Yesxb+nYQiaeombXMDQ5AoC6UJDO0gp6IsVkgiHaUwlSxeZ4ISh1elIaAQPafqnRerXKm7vezJ7bVj/KMrxljJduuZb09i7ipLh/yGAWhpzxkT38EVIgMz2ktOVkMo4jQ2Z03nvGdC6FMl4R7aQVsFo/1nQgrDzq1Ow+m4wgcuZHih4hoJaia85zVq12ev0rpmOm2ErPokb2n9Vk+wIDtnzPkGxszqYftR2StgNnQHHVRCqmsurNmr06rikUBmzZ1Z2XZrM/SFtz1bLBJoHhmT/kp6bqL3LvM5FwVucaxt4jy/mpvsUt26m4qmCb9lhHmi6LkNYjHIfiOyEzKNDdmWJ1j/9cJtFtBUu6Myx72Z/U1viHpTRcv4S0ajpRM4Z54Ut2DuK7Hpvtte8PPvIos2fP9j0nAIMnAVDzzjBq5w8FXeWHG6q5emvh4GZ3sznPLE9WkV68nFZ5JF3adwmkTZtQKJW6HxTLQD35xKMsfb8VmfK3CX7ZOZv/XjjdSLQ9yep31qIo5rOtvW2ZZ39P2vbzQaJsF9Gha2gWVsB908tw75noyS4AXq08nafEN1nBidwzcxyby6Yy7Ni3UVS1V1JbfdpsQ0ujMd6v91fcB9Ppu35efVahLS/1oAu6ZvDsn95nzr3r6Hz2WbpeejevjPBZaPHGokZmrN7M8Ys38lp4EgDPt3Zx7RbvGK2hfif3/vMvhJcqjMoMsuojGBabwROfPj9bzkv0OLhJbQN2fO/ATvPkDnwpVkAz1+/lBzVtktoURUEaUfT0SgxD+n8vbpKc+9wfMP2oavmNB1sZBqqiVVlSmx9y62RIyV92NtIlvPOoWKYrLz0wmN95ccAb1H3+b6tIWb49v0/uAfEjHhbfcza4iGhG0PT5rT78WN4/7SyeS/Q9XnCnWQsE8gPMpZliApH88UB01JK8bW5cL/7AoiKHcKZqYV/imCZyiAUhc549dMQuhDXPfcsKPU1JrqZIOv3eM4Fv0DhoWK/1cCNieK/lTq/ll/4TzECsrrvmUlJgWAuD1g0qrILjJrXZhIPeVHOkUJjrIh7+fVYxsw/LT0EJ+fMxMElt7uaSpsiHzOWUSOw8PS/F3p8m/Iy3px/v2Tb7mDPR9SC6RWpb+N7FxHqGeu7LRkTXQEhKK5wxUJgMmY1fRJcaTfJkcjGlx/yGg+hcLP/Fb+U1Zk2lYFhPFwBtVjpcTQQplfl+mNXkEzbd8CO1qT6EFjtt6LmYiwZsDsuJFrluRJtpRysyejYVLUDYECgulkXEIsoPTvTw8OJ8Uv7z4qsAlNZ4n8cP1lUxyyKBuGGnkQsZgmN3beEz6xZzZJf3WxWJNajWIjiAn26MMixlMDhUwtCyU8BFHigK9f+bORAxYMv3PvxJbRbpWAE3rUHkGC4l6NNfWecrDk5l1CHLGD9+IyXTmygf3AWQTYXdj5p5SG1+afoKHaX7UDFEqBfCp4vUlqssaSOXTGOTxIJoeQSgvqDshsJDESnPc5gvPsamMZPZOmpCn9cQwEjZ6LmmrvkTgXP7/FomMld8ki4xmECOEu8JVZsYbvXhQV+lNrh51Qcj5hg5YyNFtYi/FunXvTsgHVJbRO9bqc3IIasNj5pz4VyCl67n2xCAd7rNe/3UBmc++O05TgxUWKS2ppjXF9uacOZphi7Y2eOIgdg2f8jOzzO45lx6wxArdW0wY3Bh7BgmpbzjrhXixF6PD5FhFGZ78CO12YSt7u5hfM+4mxlyDSfJhVwubwGgIcdG2+1Skabysb32OmL0/r02vn9x3rZMppjWlsn8gLv4mfQubDfCLsWzAkptk5pGeH7b7XnjhrM94yoBnLpjPcdWe7W7dC3Exo1nseb+w11lnePsOIKNYD9IbemMM1+wv6EAIdwCe25S26aNZ7Hwva8jdmNh4b7GXlm6LqWslVI+IqX8tpRyInAYcBmmoW7GfC9HAj/t5ymbgcuBJ4CNQDcwCFCBzcCDwOlSyu/KAjriUspXgZnAfUA1UAR0Am8CF1rHfmSealupLWA1eLvBSUP4rwQbwAGHzue20XL7KjK7zAnKqsY12X19Nb0nf/tz5txxCx3PbiW9vQutY/cGIbuNkNf50d7uT2i6dEPVR07UeLPddMi81R7NS7OS6EoS3dFBsqcbo8BATFVVRFCgWAZO17wdcsYwuH1Xc68B+YII+A/AaF7vv70PHCmq+FHwJQCOV7YQMlQXAdaBrTanF1jFvG256fhpt1ZwawXU6dJpMz1JSWmUCROdgUxXlxO4b7jdlPxPW5cyEk4X3PbP+1AqzcGrTFsKetGctuuKGKTT5gBw8eLFPPjgg3zrtW9l90WjUQ9Z77VW872/Xm69L592GFNjvFr1qu+9dQrvpH7oUIds19DWRAYNY2+noz2AsA/s+EEPKc0kJ2bgUckOKiWgI/8rldru2NXM36qb+O22Oka9s3qfXktKiVR3b0C9fl4di1/wV5vwvUba3/Zqqp2SxrTvWlklenEpC5972pPSqanpJZa0/oG2wSEYd0Kv19J0bxDh/ab32dC0CWn0oKfMieldl34977jU+vV0PGCu2MtdjT91dSefJczxG7qypPSMrpKxU5720kYzLodJnlKbmmB40JUmNd1MW9Kr+rYsuvukhPpBw+nuI/2ouyYRaxYTlqbK0jili7OD2wBJStXRDUl7sp1rF13rWVbXtGMhHfXeNCRtFea4/LWahYxoNx2uo2c9xN9+eQn3nP8N2oqH8tajb7G+aUX2mAbGes6xfMkiXv77n4l1dtCwrQuAMgW+tWUX1+1o4IHV99OTNCfbdb9ewOt3Ps+SxU567o6wTsyawLepf4CbD4NoDZSY9Yk16CS2eYn4FYo5oQ0Hwqy+9w0yNSeRkkd6yjx+2md59nPfRjGCJCKWUrShoa1t5T9b76aGiUQrvKvmvjvnu/kPH+gaO4+6aY+iKCq6W4I+2x4EBpKaeASpOWPLmh/9kExXjEBRlCFjNjJy1DZ6IsVEi0rz0s24kYrHEQhCuQ4kPYKilhJ0qRIlLGdSXXsbwoDhk5oJlemkgnuPhLK/Y8CW7z70ZBJppx81bKW2EIh+ppf+L8D8p7aw6LntNGzt2mvnzKbvcAuMSsm//7KYp65f5ntMb0gnbFKb14HaGHMWGnXFummr6902LV26lGVLveQgXXfGAoWU2roz3WzrzA8I9oZ5W/LVUlOW872k1HG2JmNm37bu3Tps4UnV5aRsVroAaFq2quC1+iN0ZSQ0ZFonZZPaXM3/dUtd9c07HkUWcJDqus6NS25kaWMOuSoQAuFyOxoqs1u6eKBQunLDIGYFNYoDKo0t9TwdWcR6JZlVausPqa0hleHS9VWoFln+z6eez58/dSY3Hhnh4lNK+NmsIhIun7ZNIMlMNuj8ltanz6OrJcm4mdchjmvkiRM/wbZS5x573nuPf55/GUe17aBEgmal6YsLqy09bSq02IsGdMsZ3UM5aUuBR1EVhKZiBAv4FyCrMje/M8atpd4gRWq1o3CqCGjcEc0SYQy98L2lrbl9e02UrpcbiC0KcGSX950HMvmLB+uH+BMzHmr1fjNz336dWbOeYNq09zgxOgMwfaBNw8d4yrnTveUGKg9mDNjxDw4n/ajTXs0AttKv9KNaJu1KP2qdU5Inv/5aa5TbU67UlR5SW/+V2h74vwU8/Qd/e3fXmrtQreu2Jzt4YN0Dnj4pV21xeTTO33c1c2/kHO7iCn52oqmU1hA1Sdnbt3tTJ+mqwfE5ghm7qrrIkpZF3+MfQ/F+2+FwnNAh5ramXB+gD+w0a0IaKD6kNjUwNBuEdSMT2L1gtGEEPWkgbWg55CJhtRtJIKvUNkd8HoBSLcEU+m/jz5Fven4r0igoX1AoHZehCOorhzH3cDOF7uJFX6E7Zoo7tRYpTEr4z28U3AFW87nqSu+hP3fd1k42+96KZIxh0rsoq33d5/OOLXf5isEkJOc+7/qWGU6dWmb5pt/zw8IRZ3nSj9pB/7zAsQKVhyY8xIcIadKth6NLDUXPtyFjk+Y7DqBxHi8zDTMzTUpPZtV9YgGdjpJyasQkj1qOjVvEr2msm0YXg3zrnyGMmnJ8Gx0MoYvB2d+tDOdmfo0UgiMyG5iJGTPSrTHTpLrt/Pyeayi11JuGptTsMxACJpXNIOgKzh+3awunbl/LoS11VKreFleScuq/Ieb93mppIphjZ6/vvoYRmONUA0lQGkx0KQDZOD4wFaEUMyQymuFF4/ladYrX5sUpDkQ4uzxESFH4xo40H1+TIBwemnf8wYoBW7634EdqM6ELgXCT2nKKioAPqS1LcnKSIgdDKZSAt4/pV81c/sVce9Ib/FSiJo8oHDMUrv7L5g4UqV4b61Ys+9+q2ixxLoiWJQiVyBhTZd8ZuHaH1FZOd9+FfHAyCwGHmGNfU9N7T4lsYyUOCdpN5J7eUMVxNVuyZLJCSm1hCQGfNM19IbdFRVrqKKrbTsDqX0WuUpvdWnsZUqk+pLZRjU0UySBFBPNIiYXbqPnOFReRb/p2R4FTWuOpioy3MtLF1JO6wvK2OdnfNoFUqOUIo/c2/g0e4QtNcxg8dwQhGeCKrWlGJgu3pStq/+b5HURzkdryx3l2G1mz+jOMSrXya67nCv7GyZjpWBtELvHcJrVJxuiDs626WJdZNTk/RLX88YKmhTGkQMHII9wFFWc80tnsxAfGdTjjp7UN3uw+ATRUNYKUgWybsdvsSKMSckQFzO9CQequ/s5zq977scdMSi+ktiKZ5gurF3Dh+3OdsaJQUFxzGvdYrqtrFIYRRBjGR84LsbGv8rHErX8JIMVuyo9JKZNSyjuklBdLKY+UUo6QUoaklOVSyulSykullAv7cZ4dFkt+spSySEo5XEr5SSnlcx/stvYenPSjXvaklg4MkNoOUJxz87vcMddnomv1B/esuDe7yZ3ysrutlTf+eTu6pqFn2d1W5xs224nM7GOlthymraIonnQaNl5v66ZTK9wpSqkjrZGk0Yd62O6gpvYhFi4627OtdVf+SqnTV2zl8JoaaNYwrHuqVrwT8WQyiVBE9hmn271kp/vq2vjDzkYeb8gn9r22vokH3/Nf3Q7kkdq2BkO8YZgKZj/duIvvrOvlWB+8ErmazwXMwICB4Ie77ucTbflyp3Z7GjJyVHabm6ltWP2NnZpr7kP3+F4vk3FWcI4YUZ39+72F55JM1rFh4/+RyQkOG0nHgHc8+hoiYKlbWKS2zBbvqlA15ZRXXHUcnh5OVZfzfJo7mkmn07z44otEo1H+vsucQKeCltpQzjeh+qyKnXOnM0hKCa/T7Ygj5xEImNueXP0y74Y2ZB2hAwD20I7/V0DqSBSEtJXa7MEoYCj7rcLL/XWt/G57/T459407G7mpqon76gorYO4t9Mytpf63i+h4ejHtjz3er2PmPbmVla/v6vc1CtkxPUuoNvu55PjDSEyazpJnHuW6l82Jo5RGNlVkvCSYHdutWPE1Vi7+LQ9d9UM01em3NN2ajFvn/s7r3+Ge2kV0hzr7Xd9Cg/qxPa2srukCYH1DezZIUti9Dmlh102i6ZJdG9pJWilxElqCLw9Wrb2g63EeW/9vz/E7E2m0jg6MpDkhvfWtbZz5zHJmLizssHnriBNoL6ssuB+gboRj50pkhv8cX0LPERWcE9rOJ8LbmBTs4gvxd5j229f47f2P8/arL/Dotj9wZNHE7HGKRcAaEhnNtMoTCQCpsDkmSCabGBYzA6tFw6upZ7y5PWTa95FxxwnfiDcA22qt+E9Eu1CtxQhHFjtOh3OePpzo71djJFSQsLh1La+9/jpq5VAyg4fzYslqnipypjdJfSxR9RJksekArlkynLq099v6xSFxPlWhcvncywl1hTn93HJuOLKINYO8raFh1ER0JUAiZNaxZtpENlSb5/q1+Bu/x7vizMcHCEDzkQ/BhIWcdvpTDBvmfEsiaBPOBXFUVJkhGQ7SEhF0hgRrOA11xzYO+cw1TJn5KlOnLuHxkz/Fkyedi9QLp5xNJ2IERICz47kpDISp1BZyxnCXzPku3e1Jvr9mNeeuGcqo43Zx9AXtTE33vlL0IMeALe8LwlwrLJDMyJjftErQ7Nv2Uzv+YcMmcmcVXPYC7Hmm+xHX1T3M4Rf+mKIhOwscVRipeAolHKd0sPedfWX2J7J///v2JTx94zIaOwsrM8+ZM4c5r3nTaxqGm9SWZv2CF+lo8Y6jLnn1Er700pfy67Wtk+Y7VmXnRYZrvrK5MX+umbbsc2SoM6eMu9TX7IxjmVBPNl1b2uruWxYWVq9RM/133L9dbS4Q6hFDka7Ai67rLGzbQazI3w2XUTM8veVpLn/lcubNWUbHsOVIDNj8H/S06730slodgHgraWsVuoKkusece9YGJassf3p/SG1/3NnIK61RNk883LN99rgwWyoCvDsyxFMTnOdsk9raL9dInmSgW+nmoqMXEh+aP3bRrTHgnSVX0F1cxl+PctKCLLzvHs6rXsyfF97LJxNhhBVJ0XMCRfZK8bClAJQmQlqx7l2GEboKwSA337UYdcHtvHvXH0knnPbgnmusOMpMbWIkO8lUL0CmnUCTPSIw9HYMbQGZTL4fJaUbNKVV6ntSZMId1FS8S9dYM9VMLCeOMawrXyFXC/SPeDZ8hOnbGDa8hqNmWinOdUGstMJTzk30UGP7fl6xH2PAjvcT9tcV8Ci1GQgRMPuiPqCm0oRySW0+Sm3fXl/FH1KjcRVy/tb7T2pLxVXaar1Ea9sfJRCu9KOSf6z8h2v+mU9qs3/1ZAIsFGcBoASTrj0m3uvs4ZmmDgxdkhHeug4rUVAKTAA0nyB8MuiquxFg2vQFFA8x+zKjyzuHzkyLcjn3krDITIs5jV+I2wAz5VLAJ/2oTgBEvu1aHdmSt83Gdg7L2yalyCpmjco0USp7mC7X55EQ7ICpgUIkYs4vymQPx8brmJrYzlD63w+NpNHzWwhZMBVlIYLXUyeey8uzTmfrqAnoQqDrYXTpUr0qQE52E4KDFvlLGKN9y7oqCEBH2OnHj2yo4lZ+5Ck2tC1/zhbKCZr6KbWlU6UsXnQRq1d9GkUtJUbhFGRuzBs5kwzhLGnBIbXlLjAwGHZCLIfUlkI3FJPU5tNt2kLeuUom6aBpMxXDQFcUnjnh4wCU4p+OvGPnJylZdZ3vPpUwesZKwU4Jl4v7uFI4vvhn+AarxPF0lZSjGs6zNaw+KGjFh7rLzOc1LJF0mDvpSiKBYk9gO2gYzKzfiQJZNXcbybBjUwM5fVpI1xA5QfGGzUfx/fpX+HJtisOjTgwgk2PrPx4t5eShZ3HumEv42OhvoIgAWo5v/isbU5y6OUUkOMjnKf3XYMCWfwD4TcVtoo2GQSDo+AZzfaFepTaz3QYte60VdWBYSphKMJMltfUXAtANh4DVX1KbRPiqRJVSeNGV2wza/dW4zja+udiZrwZdRF9DL3alH9WzBCEFWZCw9oB01Kl2j9Tmn+q4N1wnf83FPOzZ5ii19Y/U5lY4davX2b2TTSYLuMhBH2vW+FhmBolMhafs7uDbVTm2x9AJ9XRliUClmtMKzfSj5t+lmcLxcS2rhmUWnlC9C1t3OIjiIe25y+VBKnl7hSuur1l2eUxzDpHe9ZkYOYQud4yrL1JbhAxjtqTRE6VIJEUG/E91YeGQIul9JmEyjMKcX/qp63rbZf4zyCX72W3g+MwkDjNGc0l1hotqMny5Vu1Vqa04McZnq4K0nm/u9xF2fXvN1Y7PoTRtfneH7HwSJjhk9kfkRQggkzbHfqftWMchxREqk2Yf8LnMceSaBz8Fw1Fdrj4jZ/Wi3WZ6+5ZLiTEm2s6weDcR3bTxGRHwEDNP4T3Oib3DuPoG7GcuDL1fWfw+DOwVUpsQYrAQ4ktCiDuEEBuBesyc4d8FJgFbMVOJfnVvXO9ggJ1+dPLQqwGnwanBoHdSPIADBlVtcW5+Yyvgr8QWdkmHNzc7K1ze/OftrHv7dVa++iL/uPgCdry/lK9M/gXHDPk4wiK1Gcn+OUdmz57N66+/7l+/nPRbHuSsKIzFYtxwww1masYc3LuiMCFg4aKzaL7R7NC3zDrGt4zWkaL+1mV0t3YUro8LdakMG7bdRCpV63mu1evyAwGNto1N6khpIJG8Ffbm1U4mk0jVyJrAdLwbLFnXTE0NK7vMQVm5mxRmddg/fGwF1/9nI1/752LPOdM7LQU7JegZdP9CHMq6LUeyvWcI/27uZE5blNjCetJVXqKXjVQqxauvvkrAh3mvW+z5abGteftUixgx83hHCUif4Mib6gHv+VqqvW1h87ItrF+8jpWrFvnWq7i4hxUrv0pT02ziZU7blVKyZtcq3hoZJBaAktOuzO6z0492Vpsyyu+3m+eefbujWJiLL1e7gkG6eZ1Vq1bxiqtNp6wUd7kKTV2pLkpSASY1OlL2G+fPBaBDxNgRyF9VZjvSAWoCbbwb2pBX5r8FA3Z89yENaQ2UzcRl7gFjWC3eb0lt12yr597a1r4L7udIrGqx/tdo/2d+auH+olMby87USUhNo/Ha35Fct45kKED94DLUhL9zQVPN1Slq/D95+x5ZbNrIurpHaG01HQ0CmU1H0xVdTmfyCToa6uhqakBIiRQRTjw8zMtjghgZHdQUElg9/Txuu3AWrUNGApCMFLN5206kZpCp7bFSlpq2YVxIMDas0K1LDCl5cWyQ1oi5rz0gqcqY/d2rDfeTtpVBpKShK8nzK2uRYYUxYzZhBz/S1rj0c2IZuqbz8u2reeTWhVz5l5tpqa9nUsRgFcfyAx5hrjyTo5o+43kOq+qjbDv1NGp/+jfiK5v5+1tb2To8REum/8EeP7zyieuzfxeVtLJqShE9k8qYEOjKbj86vpZy4OOH/o5I6B6GaoMYu81ZGdxxyHCqJ03h3DGXcPSQczi6JEDSUlH5WP1MBmvmCqt0chgtmLY0FjFti+JSqGvFsbOKYbB63GE0Dx1F+9IGptf3MHbMRrRKZxzVbr2Pldd7bW1qzGTSoybmeTbb1Xvp0b+Clh5KRg/QnOr0qPPYOL5EZ3pVOQLTaf7yuBCXnpSveJcOBagaM4H2ikGsPeMYfja9iKRi3k+jGMvgHkll23DKEkHOXT6SVLiIVUecSLgyTSCcf92hw2oIBlNEinoQtiNQSN5reR7NSPPxc8o47+wyzv1YGYnKQ8yV9iEfh06mIm/T+OGTAVj0zOPMjI3leylzNWZpq0luy2hBdC2C7srRF64dycO/Mr+58R2mk0AraWd1Yh+rHe9HGLDluw8hTBevQGKErXZDCBDo+4nD5oNCyt5XUkZVjZ0FlD7cCBeZE6xMgbSNu4OdO3dSV1fHqlX5qmKdXaZiTaSiMW9fX+hq6WHq+VeSLP2hZ/t3hjrO1NV0k4608otnvXMRKSVSSla99rLvuXXdWS2cSnYx4+1LaLv3fE+ZHVFTBfZ7Dy/nwrsXZc/b9sB61LoYuhUQtIlSAI8tyZ9n2/ZZlDmO455KJ9VzmSXJ2n32b5h1jEk+0wyDRADWj/CmtgBTgRxA7ePd2QR0gEMyo1nJcbwx+E7O1H6T3b78LZNIkBmcfx2AZDrJ6Phozqs7j3eWvooeTJIuMsebWso1F804geGqKnMO/dTmp2he+RKvXPNdMu31pCxSmyYVtiom2b0pCK+XmbatL1Lbpa9fysJGMwWt0osq2bsjneesrX0GVVGQ1iY7XWHTUfdRd9zNqEWtdE54g116hnhFEDXi9UW4Ayeb0zF2jBhEw7BDOVQLYLtdDSGRlprzPU1PW0oKBhGL1JaiiIwwHflDisII+/29/wobnr2TFfMWsfSFp7PXyX0KEhCBMOgZpOq8U9urkel5hiO+8QjLV55AsrqKTdOms3jJUlRD8t31VcxatIEztu4kVtIFwM5wN8d/qpxdZV5fwsyG/BQyqVxJ1QIYNDhfoVAaAjUnzao7oJHop3LDwYABO/7BYacfdSsTmKQ2BdmPdDlm+tEImkvFwtD0PKW2/Au7zr2b6Ud1tYrNi+b7xijVrP0WhJUwmmtR5/3/u8BTNmjdu3vB0rAjX2Z7i2lzhLX/wtU7uGJTDYtf2OFR5QYoCgeYPHOIVd5bl6iPEpWSo6JWUhJ1VEmKvQSg5SOOpkMMY5WVrvEhvp/dJ6T0VWozgtKX1FZc4hB2U0TodNXtd+LP+ecxAlmS1ZfbX+SffJvhtOSlH3WT2spHNTJXnkvKKGZy6yCEoRRMK2XjY5scNe8j8PoVBXqeIts4afoM/ih+3+t5wRFFcKd5E1JwoXySr8tHPGXjOHNAu84pMcVTpsyl2gXOt7Nrp6MmMk6rpGrnsZ5yRark9re6OavTWTgetsiRP7VSgKWJkM5VaouMZFvlJHp6hmPoAbrpfRGbt24BH1Kb912ccebjlJd3EMYZ0xaRQpMS1SfVO0DQsJUdc9qexUIIGnr2uQMcij+Z8uXDp6Okh/ju01HQM+Z790sz6ybUHRZwFJTsLz0y4jC04jLOrzPvd4lcRjJhzpvjm813U0jJNOzqt6a2tXsWvbvHK0IaDIl3o0udE9tcKYWTEQLrjubXG1Uiriw2mZzLjUxJxhePzP5WUNBynrndlymlXpX7gxkDtnwvwTf9qKWsroASHJ/d7kdedZ/m/FiIoGWvE0M3MfKweeZxAYfUJkT/4/FuVbH+ktpUQr4qUWU55LAr5V+cH7qbKGVlecNJNwxeoq+BYDLmHHM8u7LKUiqhgiQXu0xF/emEU/3vn4tJsLv0sEqi2XrkKrVlVLOf/M2q/PhdsXTGFW576km5bRGBjRyltiJVY3hacogxkk7Dtk9Oewn2c0HC1B7v88u983KXOpeCoDhj2qThPV38+D9P+p7TneIRIF1kzX+EQCI9Y9oitQBJbNSurC3wkNpc49Nk1ScZsflipjcF0VV/OpDMUTXVNUtFDgGyMBFsxKZv0rLS6sqkxH62F9WqnLxjPZ/Zku/3CYW99xJEzSq19cj8Nij6IFsWIrWVyCDvdico1+CXm9IUGdBVn+9/dq7jPY9IDjLPZ/iT2txjiJKMMwYJWt/n507/JhMHTcput49fv94kzI/tamPRydOzqXIFAiEGsWnTGdljNB+y5/qjM4QrLgUckn722vaYqRfynptIG5FmvVNKMJuiGWAo7ZzduJQZm53xT0eZQUbrfz+5L/GBSW1CiPOEEDcLIVYCrcCzwI+BaZjpPh8C/gcYa6mr/VhK+e+CJ/wvgy0FWlZsBm1+hRmkK00mBkhtBzhSqQbmvnMo7ZO9jnE3qe3BBx9kxw7T+W1YHde2pZZk5mbTcT218vjscmwj0T/nyOrVq1m8eHHe9nm18/jC7C/wWvVrPkfhdcS4sGtXPoHt1mQPo95ZTWvGW6eFi84mnW7EcAjI6N35UrSJlc3IxjTVty9G6gZLumI85bNSXdVVLplzCccv3sjf+KVZTUMlkyy8uj573YyOgZHnqAGIdnZapDbz2XYuuI/WR2ahb36bFV+6kFfazcGkTcoCuOu1DZzymyeRAYEMCpbs7EBKydLGpbQsfIed551H9Pnn2bWrlb9tPoN/NtzEK52/5oRBGcad0Uh72iFadb28k9Z71+KH+fPnsXr1u0yJHgLAikiEDmvyqere7vqmFdX8p6XLLNeTpKFyKBQ5A7tDZm1k1mWbGHNKM7prMv6XnY0oAe+56mPn0Zw8n9aW/FQiNtJp0wFdP8Nxmly48N+8sGspv5pVzI0zvJN0vdM0kLG2NpP8Ic32MqQlQc/6NgwpeTee8Uw7FNcKzUOnOE6htGtY1hEyy3RFU6Q1HbUpjtqaoDPdycnrh3D2quF5dV8f8L+v8nJvu7OJb2XKNYwc83f/B3EQYcCO7ykkUpiB8EhJxMlpL8z0o/spp+1DxT6VJXbNt0Skgo5+qLVJI5kNUtp4ou0O5nT9ikzV/ObxegABAABJREFUDrqeeYa6y69gyZSxrJkwkgWvFwhwqwb42BcbRixKw7N/dF0Y35X7/775O/x9QpLRReak6oEpEVOF8uUrQDgTl3995XJGFE3g4Yt+ytl13bQ/tomWO1ez8x8LKD//XnQlyHGldgBY0qrADTOK+czZZSTLd2FEvCTyte/Nt8rCeS+s5BdPrWDEaQmmHPo+w4ebdt9evR9kK6pqEB28jtuPEjx14idorzb7ygWcQ0KUsogz6CrzPtcX15irrALDz6TzmXwydn8wRtblbYsXOfar8rNOEKC+clj2724R5P6QaXPKyjqpOeEPjL3IIcPdfsyvePbT36EnnCGlwPiwwmBrBfSR4jAmVE6kaVCARmM8KWHa786IeX9uUlsCx7bPrDfHdI9c9FPmrjGD+OWn/50dpz+QLdNmkdpG+Uy/okUl3HvW+Wwfnu/sNWIxnq89kligyzcYXAac01aM1sesrq2ikrsv+Q0/+fl12W2dRc79/F9PBffd18jIDtORMufjF/HWmV+g6GuCw86vRijeybSi6Jxw4mxOPHE2xRNM5ZXk4K2UHr2FtJ5Cd+XDlUFo1h0ihHsFvxrMn2zb5JZDKo/nK8PbaDj6TgAG13ySjqWXMjvWxXIaSLnUDQYnxyGNTiLTVdpmOKt2p47svzrjgYgBW75nEIapiyKQSFvZ2HIuGgf4lHzuO4exafOvCu7/3MptnLq07zQk4SLzucx9ZBPxaN8kODcyeoaLXr6IZY3mN/3II49w//33k0jkz+eEFWAWwcKregthzVvmgh3NcOxGW7KNSpfqzL9PPpTuwZtI5BC8Wv+5lvrfvMdrL78EQFdxKfd9/UriVjpst1Kb8sQFAIzSa1DV/EVKb21q5P1dnTyzvJbr37vD2WGnttUcB+KnFMhoBg/UtfL99dUAxC0noerqbvWAef2QgIirXy0tta8v+c3MYm480yT/jmx3Fi78Y7vpHG7Y3uWp5+vP/4BdNfdnf9f//OfZvw9Jj2MN5uK0QHBSdntT51XmH4EAmcH5862Gzm4GZwZ7tvUMMp2gWsploDqcNPB3P/EUC+ve4w9L/8BDD97C5m0t3HP9EnamZpnHSYVu63uMqMWcvHkkWnAiUSN/BfeSxiXM3j6brlQXy5qW0Z4y/RBxrbBDt8tFxOp8czNLpo7DjkupGW/qk51n/pyWaU+gH/YihtLA5kErPfsDaEihUVcsWHjsWWwZPYxtwywHtRUkV4XBj6Y18bfg97JpjmfNeo2hleYCO7dNi45czaDQYDKBIIeXj0BY6iztdTVIq3PKXUAz5+gpGMEIyVAZ9UMmZ7crAtRQN4ZNHBGw4j8PUj98JBckI/zvlhrmdjgBtWhJhNePOJEnpzrqPpGk890EffrGtjLvd1WkOn1FskB6PRuGJhDhXKU28x0nk2Vomd6PP9AxYMf3DvzSj+pFZQgR6JePXVMzBMMRj2tU0/S+D3UT5nYj/SiAGnuBV269yX0y6z/hUUIoD5ejqYWJeevfqTUv7wpsby4bnfVPiByWWldzgoTln7OdFqkgDEtVM+uyTTkKN2baxFwUFbmIa4pOKJTJBhEzOao3oy31jTZM2zEUxw8X0nWCgQrWMMtzjBbQibtSjRoo6CjcOvJH/IvvAfB7/shPxQP0Bk0Gs/OOIdJOyabmkRDsZHQGCg/wQx5QfogWCBI0JIZU+gyoTm2pzf49nBZukldkf4dDFeza9hdPefuZ9AdaIIAmlGx6KoC64hAX8G/OYq6nrJvUZgc214/x+uVHdHdy6QLHz1EuzTlta8pRoZ2YHs7Mnf/jOW54t05ru8Y1G526lww1zx3qMG1tmiLSitdG/+uwr/L6jJMB0I0g/3KRGm2MThoMjptjw2E9XZ59gSypzVFx9YNbqe14lqEhSeleW36G8Q5nb1lJlWLeQzBnwZh95oChe/zo5cS4fO0znCrnM0Y677qhohxV8X5fzrkUtPbJBevs7qvOCzqEQptwmQgbpMZP5YfbMzz49kYCUpJKVbBg/v+gt5pK5LmktkhzLVNkpUep7Yxomfe6rk5tSKybIk1FAnes8JLh25UYKTIeldlcpbZIzmfhp9TWMtSai8v+EX8OVAzY8r0PP3+y/S2pwhzf2ugrVf1hWtAjgJQlUys6SsBsyMFgpl/ENgF0Ks6cR+8nqS1D2FclqsxFMDkttYETcFKTG+kwgzd8k7Err8wq0UqEh5zqTj+qC4UzeJdb5E85kvUUW0ptaVGUR6ACGJly+s1wfAyhdFlemULwEKj6yWXws6VZUpsVO53W7fSNy5ZewMoVn+WP/Cy7LSWc+ZJt58a3NnP8LjOebtvKYHYxt8bI8I8YFfkOnz5urFVf8/hblrdz7sbl/aq7jRFNHQS7HR+7PfYRrr5PQXB0nZn6vUjNMLbTX1gglhpEU+Oh2d/2Ih+BAGFk33lFMs6ZW1f7nmPKaA1F9/GfuMakQitmcM25KAjPd+D+xIycuHNrsxmb7kupraxlFumo9VxxTh+U8P31w/nKppa8Y9QGr0ptCJXpbORQuYVT6/PjAB4ymcz/1g3DW3f7nQQldOUMn2Wi9zTDla5F10MX/xaA5uYpVj28J3PXJOB6mEVd5jh3cPEIjwK0XT6TKcGNGTNm8PGMmapdKGW0tU5CVc2xq2iLEoh7x3HrZxgogUrCFd/lmA1ef7c9ZrLHuTfKn3Hqmvc9ZSZIJ04eMcw5uxROL3q8uoyW5sk0NhzuWeiyZayBqu8fTtI9UWr7D3AVMAtoBB4HLgUmSymnSCm/J6V8Qkq5+0tt/wuQze9sKShNZifHp7abH10/VpENYP+CPdAaFImycJHJpu2Y9KqnTMjwrlbavHmz5/f2VIb1U2dROci1+tmyGdFXqvJk73vDqHdWc1OV8+ltaDdXim3v3O5/QAHnS0lJCfUp/8DC/A7vSoJUqjavjNqQP1HX0+a1hmQq6J5by/mrtnPlZu+xWleK5quXoO00J7XrxCwA1rz1Mq8s63uwsXPxUkCSEvlkwHisB5nRUSwjuKYiw9ojK6h583+49avfyZbbVOsEKnYsfY1PhbeQOXU46Y+bUqSdiSTfe+N7/PuJ3wEw57U7uXujScRKZqJUp0/k5OlRhh3RhS7719Vu2fI0J538HDOs1drfHTWS748YiSFL2VUVyAbbQPK37i6+t6Ga55o6+FFLkpdmncHFrc67KraC5yNmdngm43/f1czWNn+VvKIicyDd0jKpYB011yB4oXoYgyvN51Rf7L3H2qt+hppKoWc0dKmhGeY9TSsKEH1sE/fVtfL7HsmO4Y60ayDoSsXnkldNufKwLx9pDi5+/uRqfvL4Spr/sZLmW1YQTUeJ5Kw2OHLQaQAEs5OG/hnex6pGkmh6r19lD3AM2PE9QHaCLXUr/ag1wVQEGZHeb5Xa9gX80lWDSZraJ1hyD7Q7QVGhBGi+8cZeD1HTKdLRu9GS7/ruf/CmKtM5UF5OMmL2c5vXrc7uN3Sd2y65kPXvvGmlfCncn2TWvgdNzs0LgJYNUOu1X+XjzGDAMaqdDhQy1a2wcx5SeJ3BZ4z5Oj1Was627WYfXtRi9nkrjr2KbWf/hOjohRhA0uVsnH/KQ3Sf9BdKFEmFpWq1eYXjJGmaVEpA6oRC5kQmYDl30tYK6J5wB7qqo0a6aCsfBIAMmvWuwUzpuVEcxYYJXmUwQ4A2RBIbZj7DD9IUvoSjRhK2Vg/FIv7OqlUTpmb/joYrGRJxxiipwf5jn3POGco3TjXrrVnj8tnjQvzo3Aru+1QlbUEngLN20nE8etIn2RU5JJvaxk1qG9fezCmrzOd6w7mTiY4xbcj/CYfUkPZxeB9++HvMOOotOkrNd7t9xLi8MsmqGPXJSpRZb5AKhfMCS0UhydQvVZPKGWqUphJUJJ2A07bxkwBoHuaspp4z2rHpl518F/GvDOeszGno4SK6LdJCM6OQgxViU4/2nF9RdIKW3Q667PeQaV2kDS9hJVrhdRx04zgKDJHfOs5cEQMEa8ZA0VDHAdQ8SmdDOgMINDXiSdnTXSz49JCJzD7z69x/wv/LroivrDyagxwDtnxPoGMptRkUWYs+NELogaKDIv1oY+O/SST81bq39UOlDSBU5Dgxd67aPaXX+lg9mzs2c/2S6333u1VlhDD7CSWYr674Tns3t1bnr9q2IfVO13mgbMxqLnzuLIqV/HcoLeWudLqF+vqnSFd3gIRMpanouXbcoXRVDuOub/2a1d0JdN1VH9W0LVuOLGb+AlMlQ9c0Dt9VZjrHhQ5Kgl++OJ9ntjzjXNOQaJpGU7UzdrlEhIinNa7eVs/LrV3omkFTt/lO6sPmYp/jjn+RUWNN4qGdFUwLeAO0AsnKIU4fO7jHmcM+YxHM17xVi6FkMBRzrhgc9Dbbt/8pWy7hmV8b2RXwawa5ArojHFuaHjURzeVQLirqYeeWr3JIsbduAF2U05MqJhbJD6Q8cupneP2ZFwBQXeOquG4GVDRDQbNclp0iwZfTF9I55kYez3wq71zff+P7vPDgLXzlznOtB2PWPRnxT+0GkHaZpneUw2meOiP7O9XTlSXJuKEe+goNJ/6CWKTds7exQrJ9+n385YgiFpxwDj2jp6Faqvt2SphVQ0t5f+JUXjr0LBDmWLK8op15fAyADhxVWY0Aww4fwoOnf46ff+ZkVnWYc+auxBusmP8n9J4e0m3eBVoCQUAJ0jj8eObPcsYKCtA1dDWJyUdkt23bvpTWQWaZZ5s6PefpLA1RNXwM740ZlN02q8fpL3JTlwFEywd5fp9Y5RBmowymNzRHRlE8yJs20B5jvb/8i1RvPLfX4w8CDNjxvQC7S/IotUkDM21Q7z725qoddDU1EgiGPAQwXdOhF7VHwLtAuK/0yi6MCAqGF5kqM7YKm1tVU3WNQSoiFR6ltlzcbhGm3Qowd477IkVh89tekTH42DPexVppawGTHRhPBgVK5du+53f3Tf2BqngnJTapzE47qRHkJLmIkbKRsnSCv0z5H24Sv/XMDzYXjUdxkQuu5iYu5XF2iUN4U5gK4TViUp912Vo2ha1MAyAiTHseRPME93t6hmSJBjqKV41bGghkrypAuQigMxaHILZoeJA/Tx2RV+aH8rZ+nW/XkFHcf+YXaKlw9esWgcAOXgalygRZxbk4C9kjadOWV43ykhR0RckeDw4ZpHak45uNZgwCLmWWr7/2IgHDnNN3xBwVlYqjqgFIdpr9fJowEQYxLary7eSDnutqisLzk0dlFUmvkDcz0urWLq7OYPtX3ApE4LRrXQ+xedPp/g8Jh9Q2VLYynFZ2iSZeL9noKfMDeSfTmmpQDPv55ZDaLHsdsNKP2lDQCaUT/IRbOS/pxHraS4rzUnTb2CBmEmn+LPEtI33VmdzXriCKYQhqVl6Ibo1fgoYBimKmKiODkBCWQUAwuWQ6kE/kUdJJbp30GEU6nNym8Y8VCcpVb9tVDHcf6exTgK8sf5uzN5uk/c4iydpgDYbrO8z0EdpQRL5S2+ETTfs+ODjE75CDCQO2fC/D8O13rYVCOT6kXiltMud/93EigxI0v4mjZr7N6Wf0vlh6Mafyv6OuY0ulQ0Tqr1JbhrCvepI7vXHIyL0vSWX9mYTjY52Yg/B++Z70oyZtKat6dQJLs/tyFUMPSXVx92JHUELRw71oO3nxjSrzvHZtj+66r1/H9ZYSUbPEYIbpjm85nS4jHh/CCFr4l8wXNrRJbaevWZYlsdkLa4a0WwuChSCk1BIUrWSErWhm1nxC3EzBvDsojicprncU122Oh+J6d0IKZtbv5JJFc6hMxVFD/qrTGb2YbdtOyf7WQsFsnRGOUtsRDVUUad4x5si2h/lezTNMHhHm7AVX5Z3bnX5UWDbopvAPc74D10JkXTC60/GjD+4x2+XEuIHoRamtOdHI4ckhjNYHUZrUcF9AGhFCIj8DTqjD+8UG0QiT4ff8htO25PuC3O3Gr1cwDHtRqvCUMeesTt3fqP+X7+IsN0YnnbHQEM20W8lkJQvmf5N1q/o3Jw1YbSptGCiKv+GsDqxhxnmm7+HCCy9kYptF/rMmNMmkOSYONTRSUuMVCrB9/0pgEEO6OtlU7Cx+t7+Jmnpz3j+ZKkZ1OvyMI+Q6z8KKIun1CX5n4Sscs7iRLVtOx2k5JgzFYFBJfjrUjwJ7I/1oFJgDvAq8IqU8uJfD7yXYE+5IyD1INjAUZUCpbT+DlKYTuhAympFdRVcSdIJ4iuZ1oAZzWM0BV0rIVLiIuz53KXM+diGLnnoqu92wVsjp0TRqk1fCHcAwdHRN9XXS/K262UynohmkY3Eqe0JEjAjpei8ZTRoGGdf9NbkmysXFxZz7vr/M9qBQ4UGbPflTGxpoaHiGbdv/TGxlIzt/s4DaJc7kXnet9o+qTh3SO0xn/Fndp3rOu2PjanZONB0SvQ1YFdVMBhgTPimnAkGiPTGUQBAJpMsEPZRx5hEv8e7xzkDi1dVOB19pGWBZYhrJ8PA3aInFOGKXwTlvm8Gd2nQTTdJ25Hu/4a3d+U4gXdc9RJCGhgYqB5lGaGiJwWE1ZZw/fwzffP/LvKfeRs/044kdfgxGKEKRS1b9J5v8VciKBzkGzbDa2qnLTSfVquOPoWRkvkLC6DFb0fWgh1AW6/FOPHNXlVRk/AdmVWPG8MLPL6doTDOG1ImrXqf7kmbzt5twFww4A7QRI6qpqDCDV+mkVwkhpcA0Aiza5Lyjbc0dlKW9K7zHHaWy/awrCFqmLjdFgglrIDthLUfPehUDiSZV2tKlsPkV33s7CDFgxz8AbMUvgRmIdSWDQBdGn5lKDkTsSqbZlfQOeLdv384NN9xAfX19XnltLxECqqJVPL/NlWL0tV96FwCI3qfet/7Pl3j2xmsA0DNbHJJ4hxPoNwJhDCWIUpkjRR0zJxbxrk7UdIoFTz6MphoFx2onNG2g6rs/851pGQ98Ivt3+bhYVt77iIS5AkoXkFgdNdNG5ZDa/t+xzphi8VCv/U0NGYoRjtN01H0YEtxZvlRCENC4bnSS68cmuXxECqPYO6YxHapmhSVQO3g4K4ea148YYbQcR2igxCTlR3tJHVKhxGi9WqX+2H9YB+2eLD14nTvT2ECxTFBZ7v+uK5Mx6gYNM+9i5DS6wu0YCF7iAnqsAIofakoVPvaxMtZbgfv1rgB+W8gMqFZqpg2KF5VwQ9H1/E78mQwhVNc7CogAU+qc8VLTDEcBx4afktqIkVUMHtyYdarYUvkSSdJyzLetCiMBtbKDH4p/8XOcAMhqjuFi8RxNjOI/Rd506yFdZ1DCGfM1jJuUd/27D/UGOaJn13PWpARGcWl2ddsd4n+5jj9i5LxCt03dyuH8jV9ioGBoQYo/lZNitVgnUWIuYNjBoTzBt7L7doz1tqOArtNy7IUoJYPMZ+EiTqghxxGnqkWeVC7LZn6cM88bynprIUQDYwnWnoCi7B+T7g8BA7b8A0Do0koiLikOm+1JJYghAgd0+lG3KuniJZ/oNaCv9nWfrm8/GM7vyDo7lxBt76StrodnH1zAr277K5q1YCpg2WctZwGVPVe8pbqZn27cZV3GcggHzL6vtbWV5ctNstXX1+7kT64FW007trFhnhN811ILs38fedYYxp1+Jz8bmSHi0+9qusEzy2tZtekeNm+5mp6R5spVYc2HDReh4fatizxKbYad/nOolQpMSt5/+XlO2TCUQ+vKQGiUTrmZssP+TLHusuOG5OWXn2Zn46XZTdGx84mlneeypWEbKYu59moxVFY2U1LSzSHTTHXVsFWvmhHetHNSeNe8D+pxVvK2dDt1bx+xmOiYebgHKEsbl3LUw0fhWdwsZFYxbGsOITkcTpCyVpAHhcyq0A4bVkNpqI0TKvOJkv/gezw46mvMnzaBhhFH5Y2Pd0UONy9r/U4HFf71hc/BmOM5fvhf0YTCRN1UY43nvNCORx6h4eqrmVc7j4AOM3dUcs7K8UiCWRuWLComUezYmUt3OHVsd52vrnQXM0+fl/297LoHkYHCqoHBgOpRHY2JcmrG1VNhjZmaj7sI/cTLrHuz6mI9Tk0JIDEoLo7RxjBahUk2b8AhtusEuOmQU637DtOeMQM8E85qImo8yOaL/4cb1ngd3NMHm8F+Y+h73H3O57PbbZU36VJG7WgMkwn6+3NeOXZa3rZhqmPXfbjoHozuamNqUw1DrPTfnQxm1zqHtBaPD8r+nSbM70b8lUUjvD6FnbFpbNxwFqCgiL3htj4gMGDH9wCGbUNcPaIiJUIEkPROanvsV/8PgEAoCK729sZ9a+lpzyfreuCeExbIgOGHU8qCfGz0NwBYVx/l+E+V85ZlWyrSQ7OktpAMMVkbh5rJP/fWrVu57rrraLDmhjLnW7HH6r+PCTYOd9K0fa4yiGHts5UlUgHowv9eO/tNarOU2nLm5jZZzU1qC6IyllrUQIBEwBx/bdzl+GOXhU9ka/kkJLCWWdSIyahi98f0z034LK8Jsz8cNnQtyWQZiehgVBlm5YrPsnXryayIncbz4qtW3UKo7vSZhmap0vV/TNhQM42W5slM6SncHjKEOZT+qZk3DxqRt023FGFKSPLF7he5if/Hn/gZw3EWH4zdZLavTMhLZNCVgIfMpKY76Jl9Ge8cd3J2W3m8JetHBfjBi06cIpao5IfyNq6Xv0AISKeL0dPmmGcRZ7ChcjBDMoKzMt5YwvzDZrFsmPlsD5cbOYnFDLPqGzLAfsahnAWTJ+vLKNuyklBHC62tkykEO/2oTSDLBCR6xOtTUazFDkHru7VToZZu+goA6bRpawOGTq0r3XoAnRHaUCYuvo766iM951wxpHBs5NKzDkFfb/gqObnTlgUwMIwAanSsJ3WePQ1OoRIhRLk0x2cjDPObUnIXl0pJWsmgYCqvnd6mMy7pvOtvRmf7EtMB6sLNDEn0MK3ZiTGkUT3EokwBVTo3cpXaRlZaC+r03fcHHaAYsOV7C72kH9WF9MQF3X8beRFDScXERfR8Pr9PFkLP9gv9weN8m0yOf+kWfu1LXM1FhgiaD20sgksVPEeFSmCm9VW0ouz4Jleoyp2SOXfmUk4PU+RWIjKZlwb5i507cCVuQNEjeQTuIbKNIzq6AJja5PQNx2+w5+FmZXQlP2Zt4xNyjut+8p91d9Sc53V3m4tqSwoIg4TQPErQ4BB4UmoXwZQ5hpnU3sQXllWT2pJfJzXgff4hiYfknYsLV7yTt83IHVPaRDlXe7XnfiVWfTMh//GLnkN4kghu/pJCJqKAVLLkZ5mbFx4IJt/kxqo7IWDauZKuDnDF94XmPCvVEn1ZFR+S91npabMOUhdENJ1AuoJE12gOa6nl9sUtnNOi9arUtrzzXXa0LuSz6nF0pRrYGnWIkrqUBEX+fHpo2Blv/nHpddl217bxPKRUmCR3eMp70457n0VDg7nAfbBRSk3NTE+ZoIRzfzQ9W7Yz05z3zHPhHksLBBN1R6FeGv7HNjebY5PLHr+ZHzx7J2FL8d0Aj1KbG52BRkqGOQvlRw25noqey7N137D+HLa+eghSzz8+EXSewf9d6m2/sSpznBCNO4vZdeG0ixBqVpFyYn2UiEvlb2jLyUQ0NTs3UHSdGaOdmMHlx13uey8fBfbEO3AfsAOoBL6HyUBvFEKsF0LcJoQ4XwgxaC/U8aCEo9TmdAoDpLb9Ax2pDjpTzmrVpUuXcuONNxKP5xvD1p40U6+Zw3ceMh3ubkUuRfcOFpQcVnNXWzOPXfN/PFw6ijfO/GJ2u1HkBNSTbS4yj88Y658/+jZvvHIc786b4VssNr+O+msWErhzCRcsGMP0Jw6j9fbVaC4y2WO/uYq/ve4cNfuYM7N/d9Q20VFA5t4TAEl5SUf//spFRCsqiHVsZNPmX1NTcx/VCx8gbMAQ1Wz7v55ZxPUtziR33Ws7aHlmE03b6pCWlGVPjuxvfdiZkBbl9F41JU6HHi4BtbySOeFVvnV/Q75PhxCsGXcoN024klf5AqqVVuu4TWZQODa68KruH694k4banRyzw3kGhuJ69jkjhE7DKysqkdxyyy08+uijADTd9CZbn3onq5ATksM4oeEIKhIhRhdPYXnQMeYbjjmXkcN3T7bbJo6VW3KlS6ecySHn11tV9da1pWWSR255w4azPftzV6AUByb4XnPM8BNZdn4pK09aj4FBd8ar2rdulxncdq+IsO/fxuHTTKUbZeQKz/aekOASIrzhUqt59flqjg6ewMgiUzkoPrKMXUc8hR7pRlpkw4CVBqFm2QTaNgwCYNz49QBMnLSGiop25oxSSAYEnRVB4tVetcWDEAN2fA9gWH2gIs2UHs6qKYkh5UGp1HbSkk2ctMSbqmz7dlO5o2rjxrzye0pqk1ISbWnm6698nd8t+l3hdKZK76Q2Tc3QuNVRR9U0Aykld7z+Y085QwkSGu2syhlVfAj6v8y0G/FOUx2ttHIQWkYHe3KZc61vbzfJd9Idy7acf+65+ZTP1lI52SQcVRaZ6Z10AXNGB/nC1N8jc5z2S4cFGdPaRFiXzB3p7YdLg46dNoC0i0CWsdI32TyEKRGD4Eiv2s15zcs8zoVXZp7GX4+dyKUnFjNi5FWMWmI+O8UiRbxlnEyKInSCBWXmvxCaj3SZ0RLDh2QOfHLDUt/tQFYqHyChV1BONynL+Eukx3G0ZdQE/nP06awfYxIEV0aqWcnxPC3+h/tw3nNJ60xy0R0SdIfynQQxazXdeDVfifYtPu35PXToLo48wfFXXs8NvI13FddPjy9BAhk03gytoazMIXtPnmiuiJZCkEZlVaCKx4sW8FDpHPRDphGoGEXMMANBbrn9RZjqwNs4nGSpV2klZGgMSpikfMXQ0SLesUghdE58g9SYyShBxybXiYl55YqLHcLcbfwfK8SJ3M8PuaLyHn448p+estvHLCZeYa5mvFb8haXCWbTQVe6Ml4d3d6IHAsTOX8jMMecBXin5RducFZEmqa3wWK2R0ZQ25weBDkIM2PI9gS7RCRDpmkhZsdlfmqrExgFtxw0jR+Wil5RoyT7yrOqas78108It79+StcfJZC0rV13M2y/9mKdvXE7LMpXxG4+jMW4S0FQrsJVPanPs9r+bO3mioZ24FZgTwRSrVq3ivvvu45VXXuHx+rZsWSklq1pW8cK1v+PNu+8gFzoKTWEzQFoc8L+vnS0xfvHcWt5cayqZ6yGznwykzLm+4XJkdnVvIJ1xVhe/0XIo7zY7AVXDSBOPmn1vSBMINAZbKudXN38pW662qZ6qKq8KdNeEt9m61bm3b735S8/+4hJzfq3rps03ggkkEvWoJzzlXjvqFFIux+Zw1UnxoQcEUhpUTl7AqFHbOOXUZygeti27/93adwHoKHFSNkuhe9Ry3KifUM6/TvssrZZybNoK/NvEiVDEeVYG0FFSTkdJOZmwaX82Hv5VFqtn5JxVMCY+Bm3o2UihsHN0Gc3DRzDvuDORSBrLB/HmoYcTlIGsiqyN5j/+iehzz/PTuT+lLGk+p1u/dy1K5T0UG2Yd359xDP8596LsMZWq/3c9bFQV88rO4Jf8zXwOKQ09mL8IzEYgoObZoCQlBIPmO509LsxNx5rjO2mpltjKSAoS3WijbtAwNuOop7nVkHSCdAedsWBJ0PtO7jjiSOpHjvZsmzT4BACCo73KwNd+wUxjaqvympBsmDyp4P3l4pNjns3+rQa9Y6b/z95Zh9tRXX//s2fm2HW/yY27KzGCBCnuDsVdW6j8gFKBlspboZQihUKBYi1Qirs7CZIQd71Jrvu5R2f2+8f4kZsgbSnNeh7IPTN7fGYv+67v+j/5C99vKQSaNLj4HdPG66SMbRtGOOsNQ7WWl3KO+FvO4zWrNbS2mnEGI1mYc8zXSHbp8S9B7CSv6gW1GQYCxQf07kvUQABvmqR5cyer3tsBqY4HNH7CbW/RmzS/8+7u7pyttiE7BrdBmPt4daDpe8zacpjjRwupcvonB6OnMpJWPT18/LE/TpYvqZ4J0pfCIE6ajkgRtjeraoLerHS4Kbnaj+YS+ygNAf981e2A2iwWTjSHlaO90AUdb2kf7fibUaWIRwYfxet8g1+LH+/U8fuSEtlBcaCNSKQH2V6LrqhEoxU0NoxicZELUkoS9LG4bRVNJJKRHTS280v9pomIj4/gjg9jhDOo6w+RZqvzXgqdZPyORNdy+XDufgcuTlCL379XEyWs6zTtWkP1xxV0i/3LFhNEJeksdgvBAind0/EClnnCvhuTsGfiA0ZgxqkT8SKsV5hPxCwACtOSwowi89X9BiOQjJNL+QnmM7VBGkFDOtcU9rTZisgoU9bPQBgGUxb5C7gyxWZqM1BoWFnnWzeicyNHyMed32O3m377KMw4xwvNIVat2JNVK81uH8F0ml4P0+tc3mZqcgTvr/6AwSn/vnckC4YfjZ6Tqc3/TUupoCCchLpmgWQTpIiLJGEZ4KDkFI5KzHSejRLMsGly+C6Do+5x6laPy8sQcP6In3JwcionJFxw6YqC9f72o57LUPO0INOF//tXQhYLYmrn5uH/Ytmly790yQ9qSwl8bfG8r7XM8ZLXzb4Hq0bGvz/li7+XXaKUZzlyh+OSBEnpoazlQZIUSTO2FunKjrupCJR02BOzFRnrXTukPcd3eS0/5E7OyAK1JYXqA9EJPYSQghPlg5yx6jEOls/wS75PxIoF1HW4fmtn0k9cAZKTPvkg+6KBs3ELfr2FB/b1NHUV8M6rJ9IbNRk/czFpdbebPs+gNr+us/WokNKxrQQwuqGHDq3MPDOhQJHp66ZsNk7rukNS9bVyzZSqns6sZZk2pcxgfwMoPWiob0xFWxuHLHk/a1+6J+4wbP169nznHRaMUQgqQbREiaMnvEV3bRZ7t2NeaOY7NWj5pxSvWeQ9M+evP/R/gE8LmlEGFdHd5C9s3vCPQTR8UomeVCiKJxn55h8ZveA6KrtSzO4KsblnRQZfl18UodEY38jKMQFiejdruz9BE1ucc9SFzklvd/ODxW58v8hw/x65xSQb6NcRYNLwM5BS5Xqu4n55Ajd9/Esu3vI3LsQT98kTopueHs6WzZN5/80z0Swwf7AwwNBJ/g/f2AGoLTRhUv5r9ejYH/V34x6rV5mFZSXdHZS2bme3xe8xd+MyLhxYjeijOKux132fg+EYJdUbENa7mU6HiW7LHcPvDhr0WGzMLSUpekJuLiCeMuMJpbHB1C26jLKlx9Ba6Obkz+JOJ+/f2rM+w2/y24sBVVIcdN+9Uk+h4H9aPjeoTUp5oZRyNDAIOBO4D9gMjAcuAx4DmoUQHwkhfiOEOFgIsXPZlP8BsV8X1VPloGBgqOIrD2rT9ewK3M6uT1mw4Eh0fQdVbP8iWbt2LfF47oTpZ5V5D89j74ddYNeCBWY7qXOfOZf2eDtv1b9Fb7SH9oZWGq3q53fWmoo9oHgR0QW8UaORFpAiTSThZwpZsuZDlje38tHUPVk10p0wEwXuOM3Tdnr1Rx/zxC9+Rny1O1FFO9oJFkd9iQuvout+e6t1XiEiajFDA5Yz0e7eq6YN6zDyAAIaFqxjRmtuR7s3nSbdEaf+6rfpev6TrPUrxxzMquaNtFLJj/g1TWGduAJvV5vHerl/gL+Pc6sFl69t5Nklr3Hz3+7hpx1N9Gg6Q6Vf8SxIulVnangdW2b8mnSwA4BfTHCNM3VQO219VAmsKVb4/d5z+WCECQZczFRn3ZylJhCusyZESgWZgxp338Uq9b+7nIEeG+6oDySaEyzybxOKuPdXB3pEnN7eXjZu3Ei6tZWONuhu1dkQHsw2BpAwwhgh83o0JYgdcpDAC9PnsGp6tpGbKaeKx5y2HboFni3yMLZ0UUJhv17+dIVZvbeUyUQppK1tIIGA+X5Eo2UkM4LImaC2XtXu9+6XilB/HlDO4ufietJSR2KQtAJUnbXzCZV3mAMDrvGtepjaDBQ+UmdiIOjJKENpDQpeq9FoDwg+Ljfv7cDWdexWuSf79D+ZQGEdtx1zNeeKh3iFAyne/W7KyrchrISLkRK0LDON5WHDFiGsCMxGhnLtlCJemncUHTMlW7WNfdzh/37Zpce/mLjupAVu8ywxkPkBWF8zsVu0NN9ya9a6LwpqW/zK89z1rXMpa03QP2CwZNl36e42k9Be9iaUnQP6FlTHMEYKXmzqoP8bn/JIdE8MvQ1pAa6k0EhtNqvPVKExr98JNG36JivW3sDC9SadeqSkBD1tuKw3isKgQUuoqV2HFILlwwYQDwaRnniBroAhQc+oriqoNo9rd07WBfx4coQFZZOJJP0BB4CDPnyHMe1xWkOCXhJ0C9Pm2sMTNzSkv/1oigBYNO7vM5dt1PFiaJZvv4HdIlQPM9k9tV43iPxpucbtEyqZ2L+e0tJGQhYt9fvF+/InvkUajYJUNpU4QLenelFi8Md3bs4aE5QJhrfkTxQlcAM+MRmhkB7aNJ1ouJGVM6/zBWXSlp57d5QJWrt91CHcKK4GoBXTluimiI81N3m8I0loAlWmqJItWeseFGf5ftcOWMWg2oWODb9KjOducVHWdq1BwXq1kU1qC9Omu8DpUJGpnw0hOGGOwm+nDcQAZs1+jPrjbiLYfzxp6SZY1jAaiTv/SASl49Z7D4UhFHbrNnW4IiVqwB+82JFooWx7v4sSGjErvkIhN1FnJxHeFPsTFdnMeInBSfoPXM49nNfnMe12M+dW/Y6tZc10hQqcNjAAuu6+V1GjkPY+WprdxSV8e8yRGLH/jG/y75JduvyLiZQGaTQC0qAoYn5jGxkOivivZmozDP/3K2X+lmixHMHveKKBaNQErRspAz21GWnEuGPxHdy77F66kqauSOumvxUq9bO19qbM+SFute7MBLWlM4KJ3121hWs7TTZTPdLCk08+STJpzgfPNXc449b3Jvj+4g84fNDF7Fl7LCBRAjqRqhgxwjzKKVxeXkwz1XSlqzlVPJZ1bQc0Psu5m+4hIi3db/vvQtBSWMrqfm7mtoH+LFrotuyOigAft7lsWkveXIuhG0ihoCiSH9U+z0/HRNk/VcyUqNsW+/5n/s6mmmrms7tjLQaj/Tg11uaMaa091XeeilXso6pp4uEG1pZ/yFvVz7jnYhQigfoKF7xb1Bul0AMsk5rCui2P0H/mfYwabQKMyke95qwPqxGSofH0FLrXJJU0Ufz6wm4P9mmNyeDVY4Gkyy0Avu1jCS+DZ+1gHpm5P4/M3J+WIjsAqnPd6P/z7bu9oJhg8GgQKjJciFJq+uIB3UDH4OMhY3htcDVbqgaQCro2Stfrm7E9UFWH8i7XZmgqDVFZkLKuR2FT3VBn3axN9cxbtZDChF83fFg1hYfEmdSLIRgIREhiZIDatjCIi/kL3+Z2ekJhXwtsMG2urqqVvmWG1NFTpu3arZjfpZASPbmIR0cfyp/E5e41CTdQrKP6Wu9pIuijSOstzGZLbzU6AEga/thOLKjQFSkkEHRjQEKVDO6/b9Y+8kkFbuAjFshMpqW5Kvn/GNhtAUSD5nV2VpuggdXdkzDCRTR2DOJU8Rivaua3fonwt6azpVI20x10YxBCz80M/3WRXXr8yxEbRO1vPyrNuUXuHHhICMXXfhSMHRN0Gd7vVKczZp7HDTfcwG9+85vcm2S0NLXrk9JWfmBYUKF7kzvfJdGzmNp+97vfsWqVnwnLyMO+mMmM0iViPDWiH3+f9Q2SFvtmJKD4/euoq1t2tv1oLiABQLfFhuVnaksTwm+rxANhjAyWtwZyA4hy6fe+xNtqqTypIoVgS7nJvhHp8rR9Jehj4dRlivotE5x7eNyWRRwo++7ooEjJtsYPiSQMZrT5n9uemOyrPRRltb7MJ21FpX2uN4wc8Xwh6c4DIhrU3uT77bCBBV3fWspuJBLVAlb99FT/u7X+wRnuWAQi450u1KXDEuqV7nABAQ940gY4BDynGup17ZiKWITKDYdbl+Tub5T061pw/dFEIsTW+f735pi1r3AyD7j77e3m588/zjTcXEZT8zDH1yy3Yud1HW08KI+jmmZCRpim+CZiTf5izvuH9c0geJZenpOpLbrdz/gmpYJEMrKpHnBbAy/WNhEXJlNbASGqpRv80cr870YuFqThHlCbJjXfiEzGmoFGJaXSVS8bQlt5NbLI+e0tnixJ5gbB6sJvG9mgtvTXHNS2S5d/+ZLrjbHfwLTw56GKPf5sX6xpb7Afn3pygLk7+riSSPjf53x67u/i9D73A9DRcjApLdumDZDkCEzQraYHGfquWyxSIIMIBIoMuLG/jLiyFyim5wDQqBioGHybG3zLD2ju8ul9RQ8CgqP4J/16WzideyimG2G1bFCk5OqH/8Kl9/7SgS5474dI5M/DOmN8T9W8ni7Z5kMoajnsrlVLD+Djj47IYovWu0udc8s02Awfq5a5Li0V1qA770gQlfK060PuudEfU/VK3MI8qBYpSn11N5tqe517IDyxI2/LyXBvP+4v3oMLn3mCwxa/i1cqPHnayZ8upqS7m3FrjwURQE2WOoye3qK7FcvnseTjowjZxxtzqPcSHfHqzNZAJ+8UN3HnWbOIJi502NkA4p0hGj6sAQQVe+3NC5vu4NXNf2Fwl0BBIWnE2WZ8mzlbdst5XybsY7Lh7n3KFL5x6FyKtTgC04dOA4uVsYzeliKy0vW9h5e4x1ctHZUWBuMPnUkwEkRBomCgGJJr19/OEbs9RM9Wk3CgIA+rsGo901JZyIg604atOHAoqlB5uPJFtuqm7dNSkv2N7C5dJvyCOXMy1noY+Kw/K2UzZ9SVEAr1p2NDdpy9JBLhwROOpFBTEX0wnO5Wm+ueesbniUd2agoPT/0VVQN+iqHobC537ZKa+jKEIZm8VaW4aQYDmyZx+QSXra6GJhQLzNsv3Olc3cw2s1ChoMeNhQULCp2YHICWx8/4T8gX5nGXUm6VUt4vpTxbSjkMGAFcADwMNAHTge8BzwJt+ff0vyUOild4mdqkiRb9DJTl/0r55PmneOFPf/At6+pawhtvjqelxU+/uWbNz+nuWeYkm/+d0tXVxQMPPMDjjz++48FAKpmgfsXSnd6/DZYrX9HEq/OP5YZ3LuKt3z7JTbffzIu/fgU14io81WMMLRGT+f60CHeNCLJYy24RqchiOuuyqbMTHqY24TEuFv7zYWob6mi5eynpjgSxHn8b0XQ6W9EZvWZAJawUUBZ06TKbb19MMu4GdrbVuuCymq42QNK//yq04u3oAiazhRPlA3w79SduiV8JQOtHDSz/2/Wkg110LctWKI39BlEfE7zKgWwQI3m2bAS3jQrxnekFLCrLdrrv699JvdLKuuoB3B+Q3DBzM6nZd/iv0cNsmC7tobdiBZ0DzKCA1yxKBpJZlL1T0kOZmBrIooEjeWTm/r51dsIboDDmCV73W4WuZV/b+sFDUWMqvWo1L000kwBNVVOY3HCIeW5xF32vozBu8IHO77gKTWqctPWc7rrmGv4efpcl2hZuKb+M/xN/5P+N+xYNZWaiNqIWOeqsN5gNcuhL7IrKyukmELK8wgVEfsQsBh7VyJi9NxClkF+Ja/kj3yWaKOaekrOoZxDr1vqBD70UOCCBPeUbAPyxznTEU+isVZq4Z1iQXhViJR5D0IrSBa0AVWfdO04b0yGjFgEm5XPQQz/7IbP4U/DbfDxkNFH8Rv9pcwu5clqEA/Yr4sJZBejAEZjV30nSLJw6xRl7j7gQtaCDSZNepSBiBgb1mCDR7QYeJkx83boG8zhtlf3Zog2iTeRPln+dZJce/3ziMLg41UC2g2mySOUpXPzaiR34z0WH/UVBbU0b16NOqeT/JnRxVb84zU1PsXjJJehSEFVVPrBatFA9gY+nfodNS82E29R3l3Hp8myW/9HHbuTW/a7gvDVm1VBH7cHo8b+QiposEYai0vvpp+Z1WSZyWg5g2+bbCGomA9vmpYtpq9+IrXWkUBg6bBFjxryHEQgRHTGJFw49BMNTgJcUKveu3417NuZ2Ai0CU19HhtJYNivFyGQR1WmVtqDg0eB7PBx6jwQpp3WaeT66r/1oghCP8E2aqeYW8T2u5+csLZ/m2+/wSS5bWrA3s+IOYjNuZfKUlxxQG8A6RqELjeKkPxlRbNmBPZ5gpqGkaC/1B1yrZBM/wWwJm4vSHaAaN+AuDUEhUdpL2qjf+yqU8k1ZlYa29JRqbI+4VNu9hnkvf8OP+HnFCTm3ySW9WoQQSSpygNrqpPkOlUv3fgngiHW5W7bbsrpEISCzHcGEdS2GUNhWWsaaykpaKorQLLa0ZqXL1wrnOvErPmKWM+/cIb7Fn8Vlvn0mVY1TGs3kUUVvD4HQjquq/o8/8CxH0lRUljMYeBl/5rvitqzlmUmpTHlWHM1dw0/jFXFIn+NCaRd4c+WMvXlozoFOMGqxMYWkZQduqqjlnhlH8gdxVc79ACRFiPUlVWxYuXOtff7bZZcu/3wiDUmKAAEpKQiZduAD4mwQ2cwm/02SydQmZYoPOnq4Ye22rLG9OQyWd9/dgw/mHwRAOplCRp9CRJ8mk/DNbq3hTVymVHjeateWtNoZjFrbS9uDDzpj4oHsKvWFadMfVTT/fNKbdv3rk9/6iGXq7qwrUugXGUrNtFYmn7MacVyI88SDPC1MdrQmamnQh2cdY8CA5dSlGygw4g5gyAa1CaHy1ugpvvFbGYQajJNKmuerhf1xmhUvf0LD1m56xk7nqNEBYpPaOUf5K+MLatAy/JeHBxzLH8X3eZe9KWqYkZV27C002zPOW2L6ooaHDavfrHvN4w80Gbg2xEZxgXofD832M4Ke8v6LtNR6isICgj996C86CBS6Ou2JLRV01v6AD0e7gG+ppLKZua3gcafFFlZvAQFsLXFfzcn8lXOc1rEACU/SpjcYYvWw8SweWsCSIX5d9OGwcXw4Yne2l1Rw02nfQ51qtQsx0qTUKIMLTWa5TRU1FAxyYzhdL26i+Og7QNE4/vWB7LPIXwznBcbbMrRHZ3P7AsY1bGJsg99OfE+4RY29FNJd0IGhuu/iIqZztfgDXaKMVlHNn4eeTjN+NtBeCnlb+IFi2ojXGDLEIKlqPDXGBDoKDCrHZLPAekWJ1jE65caQlg8dxbCDzER3lAIKp2UXdDbppk2yLZE9xW8rrYKQhyE9aJAO5Qa7j9mebUMrSH4hv8/v9G9R0emPQ6nojE2t5YRNn1r7Nt+DKaNfZ7hcw5rISPRwhIfbTWD7C2E/222m9GcrKS1AR8SyhXfU7/RrIrv0+BcTpxtKBlBICHWnmdqQ0td+1GxitoP3z8PUpqGzbelCPnqm79h0JmORXRxr+4KTC1Q6XzPnCAkEpYbe5WdkziUig6E0pagsHDSSTDc9jc66sqKMsRnJequ4dRsDeF9kMmzmPYOcS3sx9xWzim5tUFsY/zzWm8M2eFYctZPHNmVWS24AYwldnl/mmGcn78F+XcOIply9lCToAyCp0kBK1WFNjfVsYRZ+Nport/jj1gKJInV0IJ3hTtVigsT301/xtZ/sS9py9VL3iMzRqi1JmrWV2YzoJbEo0zb7fSMbBBEPur5mXHRSIgu46tXXuOw+PzhzUfk1pI0UwajJfKMI3Wk/aktBGnJBUmLBsAM+AxfgEJAgLBCXlnbXq9bnp2iDGNTq6p7r+GHWvu32ZFIIREaLOj0HOHr21vyA6SkWYNTrmwYN01/vSWcz9/QlF4+dSGsOYGinYS77ibzGPG/DBLXts+oTznr3WedrSqGTRs8ZQzAyGYYkLNmwGVl4Mo9tvBHdMtwvWmPejzGJEorjbs4jpe44QW1Yrc8WVC3wLZ/bkLs4MZ2Ri9HCGsddtRujZ/XLOf7rJrt0+ZcnuWZIe87InFu96kf2AXe4U1zKbzzsn0Gt764f2Vrts/B2+uWNajM2d3RDi68lZ5CUow8EEIoOYO6S7VT3pvhmYi/X33YKWv3iA7UhUF45hZIF2SC7cSznNHkPAL/ovpoB26Y6HWgAhBHw5KE93T+iLptUINZNQbw3uwcqoOg71mlKDr2QTCu+46k5zK64Ab29Zc49mJZex0sfn4eStp6f9BMLCKkysMKDGbXswJRUOJso6W3mPBjS4ciYCzAeqmd3eqjtTXL6hiTvdaxnffdiChrW8sqMJl6Z2cbruzU79qe3jamdJwnGqyjuGs1f/t9ZzHrheQa1N1NusZEOb9rK/ivcWL5qsdYvSM1Cptoo2b67U6gxocrd977xqUT0Sp6q3w7fXQFlZgwl84mIjHxMbXkxFYVBzrzwIvba5w0KG0bRs72AtKcla+VJJ9GktBLTuwkqps77ZFgTw4s3UhgQPN0R4PbmEEPH3O5sM++bJ/G9h58hGI4wZfZULhj1IYowAY6K8z/wkqVP7OfmO7Qe89p0C2ileEgLjEIToB4uGkY61Xc82yaECUqVoGXXBCMBNEVj9LGz6Z1rPvMJy/+eRSh1GX9wj+n5Jj5ueYmo5gLtvT6BooTZY+7bbHzJxVQ0lpt2beWAQUSKzO9d5CESeuz7bzG5OruTjH8y85/nqNlzOfDsc2hXVVJqgrGaC2brrjqHn73/fUq6dH70aDvlduvx2slM38OfK7Bjd0Vakq7OWh6Ux3HsIjP/Utgz1BmnhQpIpVw7KBD46hSafWFQW6ZIKTdIKe8Cvg9cDczHfBoC+Opc+X9YpAAhdV9fXUUapjPxFWF3ef3eP7PsjVd8SqGz06xiaW17M+c229es4vV7/5xznS1SSha9spnertxVHZ9VYhYDQ1vbztmCL//5Fh6+7mq6mpt2PNiz/9mhNOX6Zo4oTdGqW86UmiBQ5rZ30ESaNCrrGeEwpawpUjByBEJUJURXZf+s5XEPUxuY1b1gssaUBEynx+hO8o+f/8g3bv4289n4aDStue+AAWdSFvQr5juveIv315lB7X8cfpazXCIoLGxn5KgFFI96mYQqEIk4J3Us4YjVdaghky2trX0DzWP+TuO4v0KowzycoZBOm595rLCeZNk6SjHXPVg1ka0R855si2QbP2trB5EWBprldK0uCrMKF0n8DEexauA+zu9eJ1Bu7qtUukqmJVLEUg+Q8LjEbGamRzBbH+Ows3nFmxivCLkOatkeDzOxINvgenPe3qycfjBd4WI6Rs/gqW9MoH3EQVQEstlJfs2POWUvNwjUXr6Jk/Yf7ADrGvqb70BvRnXIo/OOpyRQxeZILx2KqXg7Cj4by4pN818w0PzWBs92E1l/FedzAz+goajcAfXVM5iPqiezKDSNq8QfWGOYgff6+nG01E/kffZwti/ENFC6VNNI7BBR7hzYzq2jQ9wxMsSmOT9zxoat2MhW8QndNR8ipeIkyxMEUZQ0U6a+wNhx7/AsR/L/+DH3cS4AqYEJRFnfyfLZBxVTWTLG2l+K+src7cYmTX4FgHhLAOnxgMrLTWfcpi3WVZXrteu5O7lH9k7+B2SXHt85sed11+WzQU7muq9S27LWZJojP1nD9sSXo3e9YlcgyRzVJ3ev2MCtL71FuquLngXbkateg+tKIZoNEgITRP7RRx/RG2vg1ddGYPS/mz/OviCDyl1goPDjSf25bEYBjSFBuHY8nWUjeeoPL1O/fCkNyRSPNbYTXdxE93t+9pi4pxiyqUhl0tmrGXqgmYQzlABRC9TgVun7r+v96fvw6OYVJMJmYsHwtKWQVovsRDjMm7V7kthWhEzDou7+tCcLSOZxZlKW1254DjUx6QLgxnXqXLQmwYGRPShPSraHJQNHfUBBQTt/qFxE05iH3Q3DnXR6zIANjORJ7Qh+yG/Nc/MAo2zZTh2dlr5Qc3G9W+IFLnVQBkBNBj31JeveoSgZRTXc+fOT8GZu++bZvnEncz/DMMHPlTko3QFqaeROeRrHyoc5afsTFBKlN+ien932S8tgINo+wl9NGU+ZDvNmhua9tlzSq0UIkqRGZtuL24TpuNbhf79CRWV97nNhuUpKpH1tvnspcJhatpe5SfkhE82WQgYKKUWlQfgrztNoOYNCtpTEe6lISvZoTqNKlaTin5Mm6Z/mvK6HxJn8c7d9sqpQjQE96MJVAQYK9ZjA/uAOQG0AW3K0MM2UUcnsQEVaU+ikhF+rP+HVsbsx7MAZPD9p95xVrrlEGTN2p8Z93WSXLt85MZnaAgQMg7DmTp5SiK+UHv+sksnUlkomOXrhWn67pYnnl5h2r0220Ff70WQ8zfb1HRwy8DyOGnQqqm7qMZsRxxX3Xr04rYD/Vw8LGjqourGH6T3j+O793TRe/3NnTDSUG5T8Ggdw+YCfEwuYumVraRVdHlBbq2YlxlVIGgnKR5r6Yw2jffuJUkQoke2XDR/xMfH+5lwUsR63VMxrEYrma4sKZrvn4soWmpqGIaWgqK6XYEkSw0IebC5bSEPBFhaPH8gVtX/kMU4iISLUq4NQ8rSa+JO4nCViAnowt+4rSFiV5F5QWz+zcjYc7qG7ZSifdJgtLrrDbkA4nEygBWCfSpfNTWgwoMkNtAJoxU2OLSBjpm/ZWeT6mFJJO8VHttQziHbKHWayZQNMwKBhBURXRMbxkjiMtKqzcNAodCE8DMaQUjSePOibPD13IPnkgxETSasaSyz2hKAa5dNB63knbPrRnZFCDI+/HCs174k2YCaRpGqdj6fqPEd76i4lSVqzx+ZPSvVQjFCht9It2Pyt8CfQu0UpL3MIAZngF/L7AHzI7Kx9Fc14l/5TX2bh4FFO0qCkqIVBsz7MGuuTdDGa4n7Hz8/dk9IhZrzjO9zGPwtPydrkqbED2Tj1V0RGZhflvTdyEo+MOMz5XaUHiGq531GRx7YYygZqUy2MWPko161+wgH2q+ik05rTZtVARUlKCgq6GMRm1geG8/qY6cwfbsZhupUS3mXPvJfe32IG/PusA5BAtyfO878ku/T4ZxOnG4r3/RVWoZLUc26TtQ9pEO/xJGWl3DFTmyfhpKHzxh9/yZv3/6XPTTIZi7rfN8FH3iS9928BpB4zE1KRYvvRS1JhwwcEzyxI+XjIGOYPn+grDgbYprRnxahvGh3yL7FAbVdbLZn7S7/Pc6p4jJUbd2PjhqnOsny3KmqB2uKE0bbNRLdAbQX42TCjll8dMj5/F5Yhvbnnr0JcQJQMujZM2AiS8iR0t/YOpcNT3KpYNpJuxbkNoRP2sIQcLJ9mTtKvTwSgqjq6xFdsBjDl5Vu4M3o2A1f0ZrWf/CziLyjM1metnx7C8ppXspYXx6M5IRkSSAT9wDQFwbTOQiK9XQhp5nLS0Ve44NledJmiYoOlU4REpvzvWFFaIj3+7ixPBxgvqK23x7zXmiHBBpB52Q8tW1wNTUKVBru/42e58Yr9XPb88FVEBllEIlFIV1clyz51QdWhdH4ARiBuvi9xj78ZMEIMbOuiILlzYERblhcXcjcXZi3/dGAp5bKVMZgAOkUm6E11oEpJ2AOm0zEQoh4tRwq3q8sCazo+i/lvkBhpmXTanp2zPskzb/YwvjfMSdGpnLzgZWDHoDbFA5hsC7s5tyvuvYFr17zK/OZs1sINGfEkJaDQb1gpBSV9M9p9XWWXLv980pZK89g+2S09bVBJWvj7Kvk5Vv3fSh/d/0D439fb+Db/4KS867+M6EBJrJjL3p3p/FZJO4B8u45jn0+388DLftYwxck55GdqM4TKJ+sW8daiRb4xelIhnVA4mGe4Q56J0hJGIDA8Nky4ewi59ImejlnHhbQVYxA54sZqZvUb0E/6C+q8/uEl3MRucgGtYT8RTE4dZd2YYVanj8P0hUzuWeMwWgopCTdspE5RqN0WIBSv4W/nzWHw1vUc+8Y/nTly5nAzX6it7GTwq9sJG1Cc9gDqPPHOeatM9vCb3t3E5asTxLXRlL5xG5M3N1Bf49oBNr5PSMnu773HmpI1Tj5hqwIfhlLUlUZ87G0AdZ0tBD1AQMWj+2R4HYHHPmToajP3Whxyz3GYUcuWUCNq6SAo8caI/W9nJqjtwn3HOH9HIgPov2lvfxICUFTVeQAtCbOYakHRUgoMCYrGq90BVsZVSivcQnkfw7FmzvOFqml/RA3J8OocX81Bv3L+DFhMbboVnPKC2qgcB1dvBlUjlbLIfPLAmVLWNxREI2jlp2yihSNGHEFpyMqRx9spar835z7AjyNb272QlMcfVzykFqoaca490NFMZPNqJtSanfgMj32x9zfP5JxVH3CaB2R5zTXXoAVz68TC7qHO35nfwvRDj2LSwcc6vwen3OMUl85hU/dg1lkd0XotcF7B9Bq0QMacaM9rEtraBvL+eyfS2zyGTAkEAj6mtq8lqE0IUSmEOF4IcZsQYiWwBbgX8FL9ZNNV/Y+KRFhUih6aTqTZ5/kr1n60u9Vt+eiaDLmDgG8+8Bc+ef6pPvfXti3Ku/9Yy0t/2Xm2tL7kscdM2vGdpUBsXGdW+6YScaIfN9J488I+28TZ62onmEnNhAFp6z6MCmpURWPUJMx1mqLzd07jx+I3tKqmQ94dEHya0cZwY2U/osFQTuatQIHLLvJ0ncarVbBQ3UAyFES3EreJTV00bVjnjFvJOI5bF2Rt9QB6PY7oAm0tunWumaC2Gk0QvO0dIqofKNUbDPHakNn0UMSVxT9healKSCRR9CBasthJXD47sJvnOIJ7SueyZNhD5j1NhcyJ0VLEqppyKrsB3qw1J7/OjJYVtZ0mOCCtqKSsdpaKSHG7+LYz5m/iDBrL3aB8yqPkthQvp6HCDbJcOexIEsKd2MuleY3JPDNeSnjalZS59ylKEULLTtR2FBRz595H8uHsA5HBELGqiczoP5J9q6axdsgYVg0bz6uTwkhgmfCjrh+YvgSArkihb7muZp/coOlD2Dz0CYTQmTHzCZ6ekj/4m0u6LJp/u9peJc3ZH7ot4FaIiXwv+CunaixIkncHT3fW/3P6viypG86G9TNYsX6az1AuxB9cFkinpWhMxZcMiZWahnjXfjezbeqtpA2X6vc+cR5dxWEKijvoooSHxJksEVPpECbLXFCNs4lsRsNM2VYYoF5p5dpJYZbUjepzbLLTPLfti/0AAfutNDSNOBGnDdr/iuzS459RLLVhO53eio2vGqjt79tbWNAZ5fbNjTseDCS39qD39P3+SylpvesuZMx2cLPtghvberk+UMLWK35Fxz/X0vmkpfe3Lcq5z4ULF/LMM8/w0YcmSEst6KRXKeQhcaYzRiAwEKwsMfVnyjN1Jrsf4OGfXu38bn9oFZ1PrWfa0OlokdzBRwNBySDTUTSERtJKdirWHCU9zzWpBXln1je4b/wUeirrAUloisuualjV5W0Fxfxx0OX8qeRS7tAvZWGNGbCoHNvhO7bEbP2csEBtPR5HI+lh8j1rQ5Lz1icRQP+eHhKaRtuAMLHJPTw6Yz8WsLu7z1AnK9LuOT8tjgFwWkJWkg0ovE1cwSXCrNjrP6s5a727c3e/0mLeLEv7bdbJU16iINDNcwNL2I4J2v7LyApW9vcDmrwAOQEMbm3IecgCYhzHI5Qluymkx0mKgAtI9zK6lcp2toT9SXPhOJ6fzb7upJQgCapk144HW1If7hvcdc/wEA8Pr3TafAO8yKE5x8aI8DyHcQYP88rMKdxaeolv/S3ie7wp9s+57YHL5rPnmk95eMOv0dMG20uK2VBW4hszxdNuJZekhd+u/vPI05y/OynhMU7kKnET26jz2XpfRMpzGGq/VX7ogPRbi0qRv3sga0w+OX31MwwryGZ9+DrLLl3+GUUapNAISoNQyA3SKKr2lWRqk2mDtkdWkW7rO+GbCWp76ma3CvjjTabfZVew5mJqs+Xlu5fTvr2LAq2YVKiVSMq0DVK6yfy2LWFumxABVg4I0FGg0FZk6ofXt3XQEBJc2mAmBrx3syeUDTgCeILjAPjr3ENZPGA4T0/dk2Ux1x6xdX5CEaSIEqkw12VaIG+wP4bIbcdIC7hWqnZav63EoVCy2jCB6dN0dPZDCEnZsG7Gn7IOKc19qGqaadOf471qsw2X3bIsIFNsDuu+a642XF31o35HYgRyz5tBS4enA9lA+FC4h0S8iJgsy1qXVlVKSxsZxgYekMcxLfYJigIFdmCaKv7GaTwUOIVzxN9IoWFdBprhaTmmpLOY2tIiwGXiLh9QrLxyC2XVa33jngoezfzhE1hbM5C0ByD45uipOa/VK40lpu9nH1sbuJxnPcQmuipICTdJvXn29aTCrXRUuAHYZMANDttt7rySVA3qK80xRh8Zrm6KiIzazBWjJvMCh7Fl84Sc4z4WsxjEFqeIL5UjN9ltnUfCEwQWmt4nqAtApotJeF6BgCe2kavNN8CiIRESNavQw7kDzvUFdbRQhYEgqOpZYAtbSov9tmCB7CGZiLBly3iUQJqh1eXUplymWhWdWDJMyirEkwrM2MNkOK6wSEi8bX0BbhPfcf4+Ofo37mi/lt+8v4l53W8xUXfBhAGlADX11ehk8e+SXXr8c4o113nbj0qE1X5053wAqUu8GkWiO75+j57DJijq5+u0ou1kO8l0RivRZMLU6bqAeKSBDhHFybEKgYFEt9gnR+5WS6kK1UNW8ZfZx7JwzAhnP5mJvnyAlQWB9aQzOHDaQwrNqltcoqULrXMy9zGA+qz9dCZqSfsYsHLnCXTLb4ymiylccQJpAsSjxUSsQtmgkaTSaHNYQIv0HbcwyyeF6dy2W5Enfik8194ZCfj0VUOhP26uWu9Od5dZeJSKaSxtdI9xKn8FC3B9xEYvg7dBgQJpT4zk7HUJhNT4+KOjaGsbtNNMbQA1Xf74q30GdlG5LYPn/4i1j4+gc/UcKrqzW88HdJ1SI6PjoRCkNM1XIN+eNG2WTT0mC8icpRU0pX5DOrmYT4bWkjZSCN18J8tlIUfGp/p2WZqSBOIVzu8fLXEBjF5Qm2Ex4EmE47N7z8PFTSgIqTO4Pvs9tEXF4FevX8b0pR9kkUUYhsaniw6lq2UYSBi7YhWKFKxYvjcb1k/P2ldNZwcAtd0dzjKhw+QtzZRYy/Zv6Ztx1SstInfhdbtwDR1FMyhKZn9DujBIozit1bxy6qmnstdeeyEs+9y+7pD1r11goQD94tYyBBErSe1l6Fly5hICA83cyVODn0IXOsN63Fj8vkP25YxP32HO6lUMathC4YipzD5xFJt7/K1g6zMYI8k1d/4PyC5d/sXkl+u2k85RxGjH3XUB5AH39tV+NGt/GQQT74p5PC5OBOATdmOrMsBXGJyv/agt+8mXdnjMtBAE067vJXDBXu7eFQzLprDn4fWr51jnkHENGJwi7wOg3ekok/vYAlMf2m2rvaxUasrND2tdrcRiRXRvLXDmZimEA2ozkna83BUto1DuzPee47d827fMG5Mdxga+y69piY715RM+LMyPFxja2sAZ7zzKAEw/PmKBl/r3lnHh727hiMJi5r31IImNDxIJhzjp6bsZtXWtc6azR1Sz5heHMLyqEGHZC0WelimnbkoxsbuLs959lnEWq7eN3TAkBHPETex3QpGSwZu3MGP2yQ6ArV2BNyJpFA8JQChu3sMWvQBvtMALaiv/0dXUndifAs3U415b4vXtf+Op8jdQI66OhWxi60xQWySjqDCoZNuIiuq2qG6O1/PzkitYVrCOsJTgsZU0kQeDoZrfSoH6Fs8qd7B3ya84YnZ39riqke4mcYt9sXyA+Vv1FFJLFcKmbVpeYC1XcoPBSk8w9xmWQULW/U5674HdNVECnpz1rCJ/vNgwJDU1h0KOtuHOrixQG0BX6WDC2zehRbsotrrv6R5QW2lNP3550UX8bopbhBnMA2gDUI1wTiZEgHCh+Y2eNs6MzZcZBof3REm0zGO/wfsBsNHq556UUP3jORTNrUMLqBT3phnYZuYEk72lnMjTGLVmjCOdzh0zDwQCXz+mNiFEsRDicCHE74UQi4BGTCrVC4HRmPNkA/A34HxghEW7ukswK0MFEqFoRNfvA1jqSux8Fdm/WgLWZNeyZVPWOpH16vg/tnQyfzLcsAzaeDSN1A06X9jotMn8PDJ02G1MnfocmqYRjUZJJpP0tLVi6Lnvo+EJOrQ/uprU1p6cjdo7E/7qaS1sTkgVMuKA2ipUjWM+jXFC01MoGJQKndWYjBCtmnn/OgMepDXw4ZCxvDBxDk9N2dMX3LSlsHAgEoPumg/56aQIP5hRhjH7j2wZGCRlJIhWLmHr0n8QVNyg8lJM4NQr42fy8MxvOMs/DG9js2InsP3PaEBQoTZQSU3E/1lGwwUsrJ7AExxHozAT0kqgnTaZQEkXOg7oajGOB8VZPBHZh7Mrzcr7dCpk9mW2lLeqpUjnCO52Bv3nMrTZRNq3FxWilpgBDI3870RhvJePiiaSQqPd2Mqt0ztZKdxgcyqPguvR+jY+AZLD3Hc3SiFvBZdnjWm2mFhWjphILBAkbRsrAcHjh5zOUwd9k/fGF3Av52Vt+w/hVlXfuecRvDh+FttKKzFy6Ep16oOMGPExwVAv4UgOIyCHeOluOy0mnb9jKjuNNHON7OS8zdSWy/B/d5QLyvPuuwB/oEkJpaisNeeKd/olHUAdQP00E0inWMCNdL+lPkr/B6Yezt1c4LRL9coWhvCyp13Z7qnclXkxFV4ILuKtupKc621Z/fhQh7o5Ve8HWdhAvLbCUgyhovd8/mDaf4Ps0uNfTDKrmzUrwSitwLPxFQredHcvsf7dOTB5080LabplUZ9j4kuX0vS7G+h9w2RuzQVqsyWxYQMAyd5iGj4pQWZUzva0J9g8fzu6pbejUTPRmzMYIczltlMnlTjpYIcz0nvX7aPIgx5k4hlrcp7bI5zqbHf/IYeysZ/pSNlVrXb3qm6Kuem8n/i2rRzX4TBAAhhWMtVuufVh8SzeDu/HX2svZMrQydRO87f2fJP9+ZW4lhcqsllbY+PdwG/E8y61d5nAhDaqWK+YSYwmXDC8GujNm6QEl2Xzs4hu3d2kkq3PdT07KW8Hmq7FrL7q1rK/BRvUVlLSRFFRC8esya4k9x3H0CggSqco51Lu5ENmO4wxlbjJ1zK9k7jid8g6I8V0UeKrCtwZ6aKUIElCgd4dD7b2XSg37nDk08OrfaA2JU8CLEaEB8Q5SKGwKTw455h8MqZrHeU9HSjaUCcZsKm8EuHR44OUbPveKy1Kdd51l4h7eEKYrVy7Kc7Z5m1HUiSz7ZpCkW2jrBbj+Cm/BKAnXMDV37o6a0w+qY21wJYdsOH8l8suXf7FxJDSYmqThLwFUlrgKwVOtyWxsZPeT5pof6zvtrqZoLauZvd7U60qWDvY1xeorWFdJ3rCrFJeP+97HDzBZJNJGSmOXriW/ZeYx7m26Boe3bOYWw4rxSJz48bODo7eq5CqdDkSkwkZzNkylqPFGOADU300dFzW+pR1zgkVjNqNzvLM9nDN1KBnJtWALQxCaiqxAcMptRLcUkljIBGK6ktsu+ek0tlR61s2nzlsYRCKmvYxWdtAqpZABcfOK+NvQwJsVJoA6bT32pHYoLaUqpFKmXZFa+tAFCVFIJCkOxUg6mGRcc5T1dACVvU8oKckQpWoVjD8dr7FM+IYXhIms8oyJmN1d0bxgMHuixzsS7L6juGpXh8x4QPU8RvZVOHem3ph6irVMHz30gs2A5yAas5jWO+AjsK7lZM816dghPzvtaHGaaqZ4vxOeAoGkyL7HTMUBcN6h/piavuY2awuH8QKMZH7xTm0tA5yWsJkygC2OOww80U2y7dtq0QqXRvww9AsH6grlEoye/0S/7kaEV9BnqruuNiqQSvjH5zEMxyVd8zl4g7u52zUYbOy2Jts8dooAH/iHDZvnkS0pwIUg7Kj/okodG0vFZOBdur4vwFwKE8Ripi2UwXZbe0zJZyOU6y2UlzyChcU3USR0e6sCylFmSQCXzvZpce/HLHfE28hphSmTyd3EmxmGEYGpYt09MuWZA5defmnUOPqqgKyAedxDygzYRhIKdEzioJSlv2RVgRrBzbzi8HbfUxtUkjS0pxHS3qT7FMcIF1pxqc3lLjFPFnsNHnsGEPJ3VR1o0c3B4WgudmNl4WJcaG8meHS9all62ik4R4zM9lfK/3tCVNKAGGE0YVKV1utw9SmC4XRyXU0WeDmovTnj8MV5MGJ2aC2wg9V5kXdWP8nNcV550Jwk8xVjea5Vm9uYNV2i5lDJk3/0mpjPmDT21z05hPmdnoKVQhfAd6la/3AI+LZQKeJKz/OeR5z12THMubPP5YPF5gFbIH6OdQt/BaRzpH0NAUZv+x2KjvambLaH88ek6ri2KSfVbStqITn5u7rWxbXozy98noa4xsBGLm1iNKoaQOkVRNsoejmO6kCdYbfLgnrkv6LL+F36z7iF0+9RrUn5+PtlIJhgyXcRbrnebhhBEHwyKN9x7hZns8t0o2590b/QNuqMnO7oL9DS6RzKGo6TGHXcGq278GUTxehamGmbDuc+no/cF3t6aSks5kH34uy+zoXZN1PMZnnp61Zyen/uI2b5k7lyxQ1IKntgdmpUYQ8rUZ1LFCbXVBRZn6nXclWRowYwf7775/F1BaY+22HTdeWYGg9pYcPJ9CvkKCeYlTjFg5d8j4AlZWm3Vd93iTOG34dKTVFXPXPZyePO5kVsfvZ67X7zf0NG8bAfU9mfvMzvNv4uDOuN2N2MRJfjRznv1p26fIvV2Se2J3L1IYvzel93XcEPPPtT+T3g28Q1/CjwG85n/tJo7F161gyc6uZ0tE0IOfyAe1ucZMuIKOJgnO19nKB4rCo2R28knETkKyneqiNucdRMJwcat5y3Iz5wAW1ZXyf1mQc7Ghi1X2DWPfMEIosEJbhYXaLt4dZ/rcRHLb1n4yWK6jaNi3rzmi6nhWD9f5e0FHBi50am1on+cb8ZPBt+a7C3K8HYFVbYOr20ScdSmlNP9SAikCSFgqKNUZ6CxUVjYCqoBuuZeg974qk5OZkh48t084h7n6cC8S6aJjLIrh9UAcAgxtMVrr9Bu9FkcWCHhZ+o+S6666juNTMW65NV/HPQveJec8jVFhE0ZhKBsXN4u9B0rWLmuKbkUKiZsQtMu+/1wa8vaEJVH883zZPqrvceLeaQRjUEy4gYljWpQdEl3lsd4VrR560xwiGhxeg6H0Xfgesd0q3gP79hnvtCfc4xVYrdpERUykOBrngggsYP2kCE9ODmJUe6TC1JXxAS3PZsSOP5aABpu2gbuzhz6P9rPZSN5g08WYGFZisy6WB3HauYuEyfvrn25h7oplXUi2ch57+HDiXo26FM58GoKJlBpFNq7KG2KC2q2ZdxZIzlyCAXzW3kmw+xM+YZ0kgoiGEQNEElz6/jcOXvM+KRYfQ8MYljA+3QMnArG1822eA2voC4/275YswtbUCTwKXA5OtfbUCjwGXAOOklAOklKdJKf8ipdzwhc/2ayTS4hpBCFLbdqe7qxIFw6xI+YowtZX3NxVky2ZP0ss+tx0EZRO9O+eExpa20P3GFjqf3/h5ThGAUChGcUkrmqbx29/+lr/cdRd3XHwmr//VbIMqUzr1V79NzwemcrGZ19Kej1Lvzg4Sfv+179J2v8sGYRWXUVMQpWiQmSAzMJBCEB01hauCT3KwssUBxqQC5j57wq5yaCss4eOhJuits6DYSXx7JaoKOga+wbaptzrLioramTrteR4eU8vduy1n6+g/MnvM5fz2op+zlEl5qxDeHjmZlKVAFaHQUbyGFdN+SUz0MjhobqPnad/kBaMFSNFtpJHpUN6ksATa2+usvswGIOnffw0Jw1VoAcuQ+KDQX2UWTpvO0j+n7cdr/c2qZa2PqrVouABdqDzKN0kOn88r4QPzjj09vjdpq0VO1NLNI5vyV3fVjnIZ8LwV3qWlLouM97n9de6hPDtpLgCLXRwXAK94wFi5RFdVNlTX8dTUvZCBbEcvhmmwFhW2Z1XM55Ny3X3fOlOmIbBdmN+yRpqCWZ/wc6tFii3NmMGUfNVjtiSb3ICdFxhRkeokpWgY1rvfFCjiH5zsrI8TYdRgPwtPMqMF3tvsmxMAaQMrbSnTcrcZXhpq3ym4QtqD9hDd7hYrGcdy/MGMyNefqW2XHv8CYvtFNkikxENRrmNkBav/k6Jb80I61Tc4Z9OnC7n14rPM8+/o2/HoefB35h9WVWhfoDasb6m3Xqd9dRHRRatY8Por1C9fgpSSF3/9Icrja+lY3cjIkfNRVHMezpz3FjOVY+M38or+TVKWHbJuj+tYt88V2PVEvcPd7/jxgRoSSQP9qWcQL3NQ1qm9zT4AxIOCR77xDa6/8Ep0ReXRA45jaWEKQzMTlReJe7O2DRT6HZV0qRkM9Fa82lIzNPu2NFpgtAayQW0vaS57V8DjEGlWUjVOiJiwEqWe1i0dSpRkHwBub2X0YW+/4Fu3jQH+ILMlj3MinZSSENnMOlHZkbXMdvRsJpGQkT2X2gngKVNfZNr055k12w2EXid/wA/kdQAsmH8M8z84jqHJOkfvdIgK/iCu5JfipwBUe0BtRekoiRyJ7Nv5FiJPtRPAvavvcv4eJ03wZxclhFMaoVD2NdpyHn9iL/k6Y1kBwIGxl7heXpl3vC3BoHn9S5nMI+K0nGNiRFDlZ2tvYsucOY9RuG4pIFFKXSYd7/OvYeeYGwHOlnfkXfenxHdZLcYxJOqvVp+5YTnHdD2eZyv4KVfzf9vf8y1LDX0m59heUZhz+Y4krkWgX3bb+a+Z7NLlX0AMaTKlB2QmqC3IcX96/z93YnlECZnnaMTzJ4iklLz//tu+Zd4q9IBVjKNZejtuBftiusH3V26htafD3U4VpOPvO4mFsmLTh0vdY+qolGULNakmCFYqAt1TiawrgqAMsKG6jFjQtPOTWiCjst4VL9NVso8WwzFVYGhusi0zPZ9GI5WZLQDeZW9EWCNQqxKuNZPa7UNeYsHkXxEvLMjJ1NbcOgRdD7Jq5VyiFNBDEbcGvsPV4g8oSppbxHedsV0Wq2RUNeesp2slDUoHqprO8nN6c7THBAhZNzWlafT2lhGNllFZWU9JiVmotk6M4K263MxhiofJLKwlKCvqYtCgpUiZbVM10N+JE7dUSGLW30+GvsHOSIIwPxQ38Pwkly22BzPQmlbUnLaQLQPb87PC2v7vS+IwukSZszytKqTDGQFiIelflCZSVErJ4G6Swb4B1oYCY8a+TVnZdrNDQh55WhzDr6uvcH5vKBqMrqoEZbZtXEqHj302U2zQd7KPyuaAniIzNLsm0N/nL6tatj0gpEGN9PvYj4sTeUMckPdYYN7bS/Y+mqTqfoeTW1zfXs2wlzR00qkA7e0uy7kIeoCyGFRUbqWAGA/K49iH15x1JfgLRXNJWE8iA72UjH8OgIKgWzCRVgNfTq+nr7bs0uNfgtj+h5rJ1IaC3NnCcelnagPDef904K1q77wmIBCGSSfQePIvWDqmmFGKv0UnwIRf3s7GlihdaZ0hby7mxo2N1K9s942xGdV0AY9Pn8frY6c5BVyGVTCXkuZcEk6mkEiaFTN25wWOJjOKTPLFbg2hZOlNgO6I6wfGSRGP+bt6zIovQIm6ukQomsmiYe83Yx47jofdsdIwY4aWnq1MFdHbXGVdt0Z1us2JJ3whUFuewsJiK9Vf2GAwpdOdN1eVmkxtpb3dDGvelrWdKg1KkxpD2hq5+O9/YND2jWgJi+XK0qtC8c/P02IDUKSOlJJUDnOnaPN6wvVrKeb0rHWzF76dvQFQ1tWesUSQTBQ67BqDll3AW598zMMbfg3Aihqo6krx09t/zRX3/ZHDX3kEgLFduq9jEIChqtx0yjkATFhnJlErO5ppD7oBbt1jU8Ute04YQftUspLpIR3ScYV91o5h3qp1aLqn5SgepjhL3+gCDnrzcQZu20hpt3utqnNYyYALzvUdo4I2yvGAoEOe3EOhP0cQjFVT0TKLYKrMXaiGGGbUMDgDBRJu3ExM72bjyruQRoK1a2cie1Q0zdRnI5o6+Nmvb6BqgD8RvrNy05rnnL/Ht67wrWvsXc8kfTAB691SpKBN9NAtCp32ozWXTeXNhkd5fqsbv7C/Z0XR4Pi7Cc37AQ/v5897CHSK9xxAyRHDEMD+Kz+mrrOVa665hosvvtjcPqzx+DnPMLFyIkYG2EdTNQzrPVANg8j06RAsxECnvnc1SpH5XmRFHL/mwHSP7NLlX6IEc/hk4AJ10iKDzMjz92dhakPJHW9Le8A0utCIE0YaOy6TlfHcubtwyp0D08IL2LW2sy7AvoyPB7zk+N921zThYWFLFbh2uILBdExA9PBNpn8sFD+rc+Zn6IDasi7IHLmxvwfopLttT71AqWRXkLdTW7kqfR2bO4YiSv0kExf27pO5c6rWH0xlxX6oahFPrTmGp7dNINU9MccZmtISyu40ElNjSIsprNAq+glPMJm7heV/6orisKVJKV3gr5Xc1w1/+1qvSNWfr7R15uRvDKL0qh+gHXgIF+x5nbO+djT8/oE7OPvpR1l45W+ZMqiMmpr8+VW11NStQoLhafH83NA5vN/P9PE1VYCe5PCWN3lo8f9xjr6aAw44gICnMEzb/zpyyWwZ55vvvex7VnvE4pDBzKaWlnLgkvXstmG7c38Uze+/9wRVCiJVZgvQsPt8VZHHz9fce1e214VQOwmmn5HvVgAwao9mQukAo0f9GIAZhw131hmewgmXaMV8Ho2N5rhwKERdXR2apjEnPZoQAacjQdLzggsrRhVUgoztb9qfSImqaCR7qtm+4CzzmBnfRGVA4aqrrvItM5nasnMnqvYFQG3TToNhe5v70SNc8rubOe/mu3xDQkVFubbMkpRjE1jziif21t46BCGGwqULHMBnQdi9llEz3Hc3GAz6uht+LZjaMDn4OoGngSuAKVLKGinliVLK26WU2XDCXeKIFFb7UUUlIDUL5KZ/pUBtwYgZaK1f4TK7OIp0B1ZpPNrDa6+PYUv9/X2Ok1YlsvwcLQXWL2pm/lNuf3FbWTU2mej3tQveJ5qKsm6bWdHU/ZqZbJNW4P6Bqy8nRpK7wq/y8W9ewIilkdJAtT78ivdW0viLX1h7NyywlilVI99BVZPoGAgLhdwpKpghtjsMVHaLLC979DDdr9RyBet7NUgU+CvaXuYgNhUM5L5xNfxVmGjit2rM48xnrgMmypSWolKHTSikRtg86XaU6tU8UfEsDaIDgHQgN8rWm9gOkEI3NBZnBE290kkZ8VSENCpThr9AJGJ6hjEPo5zNFrK0n7/6uyiZzfSyM0bos+Io3gvsvYNRKt1GlKWlCmuLzH1mts70SgCvs12IEDoFBR1MnvKys7wnbF6T/UZsL6vihOndfG+3nVMuuUTm0AvrGMknzGDAwOV5QW3nrktw5Cdu4KPMcANAvdKfBLaBgsPYwES5yFnuZfmxJeDp635qan/u3fMo3il1adntNisA/RItJEXQYfMBfC3RWqji3UPm+Iz/WEYiRxcaN+I3EqpkE5lSRG7GuhunDqStMJulLST975aeVACFlvJqYhaTHcD14uf8XWQYWl+NqfhfKbv0+BcQO3BkA2UUmzlMmFVlep7WF/8JsdWQ1xh99bWRWeNeuem3NNcO5c2AVZGaWbXlkZYnFtBcOYl2tR8AaS3boHdPwNRRWpXpaNbXr+Pv8z/hr7fcxOZbb0HvMQ3+xu3b6F+3Gk0zk2GZ894bmPPK85ETSFvGuT0mpMSRgOFpafZK4UY+Cazme+IWrhJ/4F5xQdap2XO+KDadZSVYRGLANFYOHc1Vk0HX8rdVjBf5wWjS0umxHNUrTnuzHJIL0OsVUWWCz7pFjIBhzs33i3N5SzMrqhUMFjMVgNVBnZem5wcAhUhQnu5gQmo9J0X85/l/4o9cz/VZ2zwuTuD7/DEnsKi2t4VvynsBGGWYrScy9XdNUXZrjlwJ4OPk3ymQUUaxmomYjCWJRBHJZAED0/2yGEJtGYRbfFGVNBywn1d6ohNR9Pzg8E7dTQidgmm7pkSIkCEJ52BdsKWGJi7iFjTSSAlF4U6Gsy7veFuCgSTbqONX4tq8Y2IU+BJzn1UUPU2Vtg610E2wJYT5nc6S71FJC3WynsE7wS5XRA97dH2Uc11z2AwIjN7ot11D6RR79b7HZfKGrG1+3PYo/WhgXupjzkk84iz/PEyCADPlB+wp38hank7pEMgNHPkayS5d/gXEBjEFpUFE81Rh7gAc85+QLfEkMesUZR+sB9FolGXLFvmWeUFtmpWksi0CO3D3RFM7D2xv5ep/ut+kHQiTqn/OTkXz+4R6hgsXK11HyySN+SPNIpvMoq7DP3ZBL/pOFvH0aAJDc4Ptme2lUwRIhbPnkzYqUbVUFgN2eb/V9Ou/Cj1H1XHKYsfpiZXyY37D97jFXZmRkYhZetJmA2ss0FiqbSEQiGXZNH/i8qxjXf5UO4VWe6hurRAlFSFc2MWLHMK4yW8AsCo82rdNecy9f4rnORdGoiQJsSgwjbeNfVgjxvq2a6LWCUg/OWE4h+/92cDDuUDwa4Vp5yU1FV1RCeYJ6BZo+RnIG0RdzuVN4SKuKf+V81sChpLkqdBHFO/TzvBD6hFV/ucxWS70/f6u8v+oqdnIpMmvUOVpKbYjeWy0WRRRnIPFuzidzULglYR1n/oqUAum01nFIY+UT/KBPLeKQfySa31HOoc7vpCd8Eqte05XL6rnSnk9P5NXEtCyixHS6aCvNUmvGveAiPID8HPZbsOb/Yl2JapB2H2Pgx4bMa0G/gdc8l16/MsQO7ntA7UJYTK17WSM3TAMf6xbGghMAHxDgcJ3p7tgHAcYKwRLt91IY22I4WSD2kL9/8maph6ak+Z8+NDmZt76u59tVbeSiF5WrxvHmt9bWlHN2IKli7aOPp7G8XfTLczYV0nABfXYMWhbusK55/W3R01hW1k2I3Ok1P0OuzfP8q1raRnMhwuOY13hUGfZO0OGYVg3vqurMmue8z6LQr0XhCBuFRBoBqgp97lUe3RZJNl3cV1fUpQnBjPB8i0nlDQzONbG3LXm74ZUAylVQdN11Byxj0Pik7AtprB1Xme1mvd8Wqe5j/pePxtaSugIYSCEcGIW5y51C+bVWBeB7g5CWnb8OBLP7QvVbW7l5Cfd5GZmrdYPRJxkvyrnd08kxN4NCu+OHkSgt4lxaxczb9VPOXVjqs98zhFvv8L37vgxxdEuQsKNg2S2NQMcprZcjEpNq/9Gyipsk+kYUnftgVgOUJsEBjRu4ZSn7mLiKo/udsBwkmBNfhZxMJOvF95+HxVzvuVbrkuB8AXcrTieBVwo7PCDJoTVNqwj2QyqxvZtYwl0fhvx03YiM3Zj4B/+QKQodxvwHcmpzz/O/lVusfjvbvyFb31nqoUFzc+jWkAHFYVOq7V3eEIllaeNQy0K0hBb79vOBiQIVYWJx6EFwnx0waf+MZadUTuovw9wEQwG0TyFPREtQjhHbK+osIjLjr+OkYd8g6P+8RRauZ+dzwYMxDzvQ2RCJUVzsgs4v6ayS5d/iRJUcs9TdhzeyEDT+uHoOw93UNTcNuzCNf4iHx0VQyo7ZIHTcuiRodHNvhybroCawaTqgNok9KQ62Fa60WFoM6TB5p4V7NltgqGmLltIY/FGZ9vHWjVqaORBeRyD4yqBwkNIVWSQf2Sctg1qs0lAnGHWnLx6SDcP77+Ft6a0ELTmRNNX8Z/3T7/xKpe+9nu6koWEMxRFrqfwc62IqVPvZJ95n7K9fQqxLeeCDGLkKTbKBNcCvNPvHYepTbOKgFPOHGgVAArFYc2aMG8/97yFC3TLfFKRpBn3DU2a6Vveb6jdzUVQd/YZjPrj7wkoAW7d3ySjOXPCmczauAbN0Dl2T9NPr6mp4aijjuL91NCs83ex2tL3Pt0+6Wh+NsdkBNUUAekEAtivfQEKsMceezBpqAumVgfOyNixueef6W38MJmD1T8DrFd5ztkMuOaHjH7zDcIRUy8rqua8K6sHdrOxuIOCYKHVAtQ9V03RmD3reaZM9oOufMcoqYOL34HSAdxXFOfhwty2XSAg2bNxHDU1pr+tefZRWurqmaFjpwBQXWAW1MXjpg0lgtn5lEOqzW9lWolrbwjn2RvO+4IhCaoqrR/dSOdGk3HdBnrZQxShELEwMrbtJZCIHMC+SIlpmw+bNiNr3WeV4soqCsv9+IlAnhjlfef4bfZ7ixMccuGknGMFgBKA4lqQBuH6dRy811yOumIqJ/xgBgee5xaFe4sF4OsDapsBVEopj5ZS/lFKuWSHW+wSRwxhB18FYSOAlCZzW3tJGb/b9q9veRdf20FiY99Vk3b7zu2rV7oLrWBAU3eSRVs6nMV6yq8EE71dSJlmzZrs5GhO/Z+nWltKybI3XyVlOY/r1q2jpcV0OJ6/fQkfPuca8uvWmUnEcLiLujmN9LS38purT+PCly40r8embfUEKhoU0xldrtZz1v3n8MbCi7lhUAyBJOiZRBXF3PY99uRy/oSBwtg9XiY67G2UgGnsN5aUcU+/fRxH3mb5MoE+5vYjdb8xv6rfkKxrjgaTdA592Wcm3Csu4OfCfy+3RczPt4rmnCwvYLXYsI5dHR7k9uoWkrcDK1hUFOevc3JPtJmgNlVJ02Q5pb+Xl2SNv1T8heuHXcnF3EPJwFYGVddjIHhMuIxdsTzsMd6KBVt81Vt9yO3i232uP35WigMOG8RZcwq5cpq5z8HV2S1FbdE9AMEHxNnM32swEya+5hvTEzL3k/Ag0DdUuwH4QXITn1XSnpasddIEAPxa/IQbxA8oLW3OC3oY3qMzM/IR+241jxkOuKj9tt5aYp7qSq+xFPAEn5vol7Xf/l3u/LDXN4qJq4K1EdeY8ILaBhSuplsrpjkHOA7gj3yfv4rz2IDZKq+eQfSK7ABOh6eVzrCmrdThD3hfJX9GSX4yZdbWuPTLR8nHKJJdWQlyJRkBpYR7Trqcn558PlEKSZAb2JkvEfM1kl16/AuI7VrZiSxHjSlgCEl8B0xn/07JFdrNDD42Nj5L/4M/BST1isWI+N7NSKnT3PIq66MusCfZZX5XSyZdRLNizn3Rgux5xJYNw9xE6opRY3mjLc5Dsw9k8fhpvPza89ix5+2Kzu1c5jBTZCa37TaNr06J0BMQvjEzK1OAQKjud/vR0HE8MSA/KM3c3pzz++3/BwACBhRZSWldKLxZkL91YWF57qTsa2NnZi1rGfVPlFRucI2eB5juHGf4o6zf8/94JPw2qpHt1P+V8/i1+DEN9KO1tO/rBUAxqNI2QP/sT36jGJ5jA7LmbLt1pGoYHMbTXC+v5HvGr3JeT0VBNvghkKPF+LE8yp244OJVK+e6441gXkD6DOY7fxenZRZoGqB/r4LeB5tg0vOqeZnvloUH9Alq80o0Wk5Zefa1Hiv/nrUsHOxmPnOzlnvlaXFszvZpO5ISiz1PKAYj9l+TBSC8dP7f+BY3omLwWy5nFvnZqEqkaQuohsLxvbmZA2yZ3eUHymqJgVawLPu+j151KKGuIaQKmjhAPMM9iQu5Sl7PXN7mCPnPnbhKv5zJnVzMzVnLtbRBLLYT38R/t+zS5V9AUlY4JGBIgt7WAlpu2/A/IUk9SUpPMfP95ZyxxUyYG/H8IBLDMHwgNvCziHz7vd1hmcui2PrceqQhCVhz5AZ9irPOBrUtC7mMjwCpPgL6egbAZfPs6xl4/DbCY3qZOPEVB9Q2oL2J4liCqZvb2Ee+QlAmfCCeviSqQVPIBdJmJhiSRpgFzMna7l0xjy0VtT7wly2LRw3JWXCWMsxlzXp/GkV/eoSbyDTUXBYWPFdsMtnZBNGaliSVYdNsIbutdEE8TXGHGdPoDhdSnKjmTfbjPnEez3EEAAnpTzReHP49p8l7OHHjU77rCpGgQ5TzB3Eld2j+BC/AGkbjKX6mM6jQEdh5Oo1r+X951/UbsZKlA4bnZdsbNngR8+Srzu9wjlbmO5JPmc5rVaa9pgUSPMUxyCn+JPNY3LZh+8mXmIBbrDmpfSUHyOc/0zGL4649UKWbxVexj2sRev731o6p9JUEC+hpxjZls6euE34A4zIxmR/za+f3HrzVJ6DMloGp3Cz1jRH3BUhjMCG9jBGso1DtcI8h3zTX6357pKZmo/N3X8C6XKC2kpifxyXe47cx2z880fl7kBhATVNupvavkezS41+C2B5S9vuoIXeS+dhMZHnTJAYYptccz5jv/1l7AG+2dXtGCh4adiJtpRntm6VqtoR2kOSmH75M3ULS+n7t9qPeI0St2KlqGBhI4u11Tpu0zoFvk5TZ/nImA+XGqtxx4jW1uRmmvD5cY8xvBxlWcZDwAAQ/qevH5ojZukhKxRdD7h8zfPNTyGKYdUFtkmDc3VdRm5Y19vNIOOnexW80mP7mnI6PHWbvxUPPQSkqY/LWdZT29rCtrIRNVXVohp5zltYV4WntaEpxLMLlT/+JfdebcYJoq39+TKvCAV58f2WcYDTNEetedNZLaVAb7nYYPXznn4gxZItpc5V7Y7IXXsyg7RvdfXjOtrNoHB+QZsjJlzFpi1sYPLxomm/f/buX7DAJ2D66CCVH21o1R8xU6DZTm3/836+5jIlLPcVQqRgyFWNfq7WqF9R28+ZfUZ4wmNHmPvOi3m5OePoe89pi23hkw28AiRKJUHfD71A+3ZdtH2Sz4AghKCqvYOzwEb7lmirw+qNCtbrWtJtEWR1V/ji28IBShBUTLqoYCIrC0AceoOTgbPb/fHLWer8fPnfxxwQCHgBZq07tD/zvQXN8CwMMs81byAvGK1SJTKwil/QbYH6Ho2Zm276OWNn4QCDAJZdk53S8ogqV4pRrU20o2oCmaBwy4lCOOusKIqVl2RtZPsOUUe4cWHbsKIT2RVLP/1WyS5d/iRLME7tzWEZl0KczvX8bn4EeUFFz5322ZsS20mhWu+2+9x3Qs/XX6Zv/4Yvj6kLkaD9qtVYEnq2/g3iw1wHkSyTvNz/Fwg6NX91zKxPXLAJgYod5rPm97jc2bVgF745ZwpMesJHSAZvf9NsDhhSs7vyIpW3vZJyte32xkMH6AVG2Vtrnka0PA5ZONwxJWE9zzju5Oy84xyU7/wvZ9ktfMmfYHA4qNxnNAnZrVrtKzypYNIRAUVW+de8j7HfORR6mNiuPIKVDAgNw9rvP8s35L6NcMIERI9057Mc//jHDz55J/x/523YD7DVgL945+R32HLCns0x4AMLTpk0jliO2YVjnMmdIBbqHPdTLGC+EgBzg4iOuuJqFp5uArUy2tPJeU99UDBhExWGzGXOsv+g4s/2oCAapOO1UArW1FFRWOce178ryod3o6BRoBfZJubsSKkVFo6mq2td/jDxkB42aZHMgT4FJpAL2drudeMFiY8aMd/7uN2U/rrvqCqbscxOqcqcDalMC2fnl/StL2DJvCpOLvaA26w8JKcMmqTBthJN+OIvDLzNjYLVDswlTbCmKxyiTbZzGvTnXhwuLuPBPf2Wf08/Luf6zihYI8K17H+GYq65lt8OOzjtu79F+0P+08VUMn+ZfpqULCMWqKe4c63wOc449mWJ0Rk+ZzsCxFdQMMa/98MMPp7a29usJapNSfiJlDkt3l+yUSGEmwoWqEdaDgCBttYn8XcO/PvnSctcSmm9f3OcYw0KRJ2K9DruL/cAfX7iNo2991xnbsM5kQxOWVl76xkvmeKmTWO86YlJKVs+3En59vD3x+HaSsR5WvP06L9x2Iz/85Sl0NTdx//33c8stbnW0zEETO278W9RMaSNUlqSkPkVAmgrloaI4p7z3KdXKQI4a9h20ugnEhKlMQ1JjzrJjSLe/AkBFPIKuBUiMMZg0+SUnQPwXLqJF1BAjwrfEndw4Yib9pm8lGOzlwemH8re63Z1AgN1+QxcKe+39IHUDVvR90UBR0qCrwLxfqTxAG1u2B13D60OR23ExFEEaw6WslS6dbafSy4VzKlg8wAQiVBgtzJGuMZPwUNdrpOjuqSSZNq/NCxQaLt0kR1rRHCaXoLJj9hlbqno6mdy00rfMbokJMFquyNxkh3L7vKNZV1XH9vJsp6+KbPrafOs+ETMJh6N8jAv+aykuAyCeh+XuZB7IubwvSQXd6TickYA2EHmruwfKeoaPfYdAnRmk9waOFpZM5vXF3wSgXLb6WrR5Gek2iuEEZYprlvcwvMtcHknnDyRNkx9RjhtcttkRXhW5nXu7/WmCEJ2UcJX4AwBHtuc3dhNakGVMdn7vv3wBJRsE5Z72Cpligw0BhrGO3Xk3q81p/8hIdht6pvP7cU6gi1JySXHi650I36XHv5jYQGl7Wledam2JRLLhoXXUr/yKJWGk909/1frSZZcTqoozZsy7jJtqtUTo2sbmzXexePEFHPuhW+n5yZU30VQ11frlMtTlk4tPPQrdmidmTfgubaPNbdsGFdMRUFhVY57aa8NH87bYl4WYrJCZ857NNtlZ6Do53RTzEGdw/qwqto6fwaTpL/q2eX7MXn3dEcppI0oByzCrWBojCp9O3cdcqUpi4dwtsoTQqa7ZRC+RnW4PbQRyzynbxMC829TJehQkqYJmAsF4zhBKWpi6totSAgXZDAG+sWjoQkElTaI2P2BvdvJ9CvuYA21gczoWYdPGyRRtVylWTdCZ9LgXSYJOe81L5I3O8kTPjqubm5rcgHRB5wgKs5tZABDBPc/ClMmwZkutBcYsT0oSnoDqgSvf56fyai7dfCcnfvgqqUCMU+R9fEve4NsfQEln7oRQVXcHTU1Dnd/RnvKsMdfIazmMp7OWl5bXf6Zg245k2iaz8PdY+TB/wmzNMmYfQWygacN5pa5mDYqH9yRX+yFbKiybKKUXUBbpu0NGacrVt+fJ25izUmAYKjVkA/0qEhItUUpv5XKMQJTq7ROZzCIEMI3cjHCDm/zv9l6Nrq206MND2bJ5AhHpT56rukFb21dsHv6SZZcu/2Jig9p6041EAp42I1+hgM3MB2dywD/MdoLzY+aclkjoPN3UQa5HbxhGFmhLV91vPi1U2PCW8/t7gwWpaJKQFUjVPS0J40lzP0vCHnIBCSlPUDOWwdili9xz9fD9NlFesZ2CKnNe2W3TKk5d8Dyx0rWU0kEaDSMjOJuvBXN3KMmWgBuozfSbo2ohr3taMFZLFzDUUFKBZiUwdN093nMcmfNYKSuhmJTZIONUoG9Qup101rQUaTRGdbjzqNd2qJNbmC4XMHDAffRLLqJMtrOaMWjJUofpq51y61r972aIBIfwDGNiaxGK+5yDfbTEBFgvRtEYLvMt+8Z+O2YdP1E+COAD92VKPX235DJQuYDbnN9BJXeCoy/5rfgh144aiaKk6dGLeVicxr2VZ/vGeO2GzGKpstJGzuIubpCX7vQxB7c3UpkyfdHKtOWTRlsJxPKzx9gxlb5YIwJ6mopY7u9md/m2LxayQZhJthvkpYRIou0EU1uZ1sLl8rd9jtExHMDMUfyD4+VD/FWeyCX8EYBUyrwOu9WLV/oCtbVuHpa1rF+Xq5dDSYOSXtfuUtfPJVHvxgDWlpdQEP3XF/3+J2WXHv9yxPZFvTauzdS2s91QzMfgT42bTBpkhXIvHfMDTvp0HStXmazLDfTnleGzefKgb5LwgsmkxtruRdy++E7AbP2dCnbwfmA1H2hrCCkRUhaQ3sgABxXFe9FVlVTFaoZWH8iYkGvTtykm6EXvY275rEWaXoDcVrUtZ+4+E/CUtvS2lAptuIngx96OonqeRYHFgPJ2ranTNCkJxdy5Q2939UCo0ZwjymX+2F+mjFtjxio297j7LLAq56o3uyzai0Z/G6FpTEoPJqgbNNRYoDwhqC/PnsslUJow77GSNs/xVX0aSksb0e4qlj0xlpalFb5tamW5EyOd26Iz6J0m7kgc5tmn5IgBK8hlQgjghGfv5e6fXMqjP7iESEqnX8xgwuAyAPZetgCAPda6+Zx07VAAdC1EeY8Lvm5qdwvCVN3ggNf6tlkAAoncxVxqSXZcXTrvq8RIuMXHlZ0dDG3uoiBpsfukYshUL0c0mnpkOm4MYkrXSl5+I0p5yv9e9WveSiCVZN78V6x8hgRNo/SwwygacQhNn1ay9L5RLP3rKGeblEW2EAyZ73GLsN9//4s8rNrUt8lVz7Lqg5sZe5jZ/SXQ3swRTzzpG1uybR0FG/IXxe9I5rT49aOm6w7oAkAEAigZfBM96XaSyeUUrFtKsaeQIZ3OD849/bzzOfzQQzn8gvxgtUxw/QUXXMDJJ5+cc+xBw/yxfQUFTfQd8woMMG3IM/YbSd21uzPgV3uiFn51/Kl/tezS5V+uBHIwtXVSimLZqrrIjEG7Pz4LU5uag50YIJaR70ujoRvaDtuP2nrXl8eUAtVjhzQlG8isi7J/2mduCLdbmh23f1UYtCW2O/v848e9nLagFYHBpm4TjCIUwXFH78dR0w519l37wwDxhqEZBxQsbHuVpO73FxWriMV7eskSa5kQWbZQ2Jpv04ZkyPChBPX88xRAOkfB8M+Pnphlbgxa9BanffAiM+NxBmWw4N68380UBsz8X7GRsM7XZt4y79X4AWUABCMFKIoK/a2iPQvYpRv4vJdQOkXA0Kkp8xOsqKqKCCioRTmA3UJQGvLnE0WetrleSVvTxPl7DiPV7RYTZsWH970GCv12iVAUbj3gNv568F8JeEBqoz94n32fe5Fzbvozg8ZPQgQLUIMZD0vJPx+XVJnHSSUSKFZuy243XWDda8qHOuPVHOz2AAT7jiW8PGM0H+8+3r/wqg0wZHfnp/DomlGjRvnHRsoQQrD33vuwz+7fQaQOZ889fk0uyZxDHKY2pI+pTVUEgZDKkImVnHb9HCbOswlTsr92TRrcyvlMzxOzBiiqqERRd2xv7awEIwUMnz6Tfc7IAZTrP9V9t4HXvjePV747j3vOnpU1VKBQ0jkOLV3oxBAHjB3PpXc9RDijremMGTO4+OKLfW1L4WsCassUIUS1EGKGEGJHvQB3CYDF1KaKECEjCBKSwm7t+Z+VhS88zYaFH2HYPbMNg7TFpCUtpq7KZJ4EkeXULHvDbdXY/OfFnPn8mZz49IlsXNLKolc8bag8F1tf/wC9vRtIJFt49709eea+w3n+1t+bKxu6uPOyc5yxunVuzSXwOm6bQ3OX5jkoloUQSQdZrtZzw+RyXk9Iwskw87W1tJdGeC9g0nGGCFCULnYKjA7aOIPKJUE2nxXm1bK9mTjXrOK1E4MbMYNzy8Rk/jLxTF6YsZtz/CZhgsRaMBWCtCbRESM+onvEs7nvmyUlSUmPdd6ZCQKv/IULWFXQax0nd6UOmCjvBYG1LFE3I0WawuJW696kGTx4Mbpnkj1b/JkiDwtK3MN0Eu8uYWv9eHr0GPM/OI50j3tu53kC0l4pC0hfRboi8wc7BXDglncZKl3mvQ7hBgYu4/c8KI/Lu30+Wdcvu32JKlPsz4tcJX/GBLmYsHQNqj+2fJsierhTnubbZguD+L34Qda+EnlAbWW0Zy2zq5wBZsgPstYbnsedWXEdpTAnc8El7bfTL2CC2ewWtMWe9py6qvLgHNMZ3Zs3fNv2Z5vvd1IEOHaL5Mb5TZz+/guE9NymeiRtMPfd9az52J3qE328q17podg3tnBjfqc4pWnM5j3n96jmbSSTEUrJzzDZXeQmm1LdxQRJkCREN8WOU7N7zZHEPfSzCYJ0kxuFb3y94+dZskuPfzaxnSZH59iBdCGRlj5v3frVeIkcVeuJsego6Lo3gWauq6ndQEmplfxVVGJxc67oTrjz0sfMYenE833HKBm7Ju/xewMaq1V3zpERUxctKZnM7y76OXfsXc7z/TWH9S5KEY3U+lojL2Q6b4uMKiDgdr7Fs+Io1hYV8eHEqQQiO8+QVyMb0FG5if/jbnGRs/yFOnO+DUaiVFTmZrcIBE3dcb54gN/wQyTwwOwDeW/ExJzj7+OcLJdoR9T1AL/1tCfT1L6TvnEilFZmA4h+Iq9x/k6joaOioRNW89+rQhnliDWvZS3/xeqHOFY+TKlhzsWKlGzePIWeXje5LQ33ui7jz87fu/MeP09cyW7blpFsKOvzWjJFTRfmZWoLk+AceTsHtDZSnBFDqY4lKY928fRAvw4t6+1mJGvon2qiorcbVU1zOE8yh/cIe0Btp6xqpd+6w7OOOX3TKo5a9DarVrqgyd7ebID0YDblZFEpKu4gRTZA4rNKVXcH31i+gEIrUdSOazuFR5nFApnJ5qFDXYDqpo2TaW4cmnf/lRaQPC0jBEu29smi5rUb9uVVAjr0dFcygnXMS73rG2t0bXGr+4FAp1cP5/4utJj/+V+3xH1ORjJEMlnAb7mc/tINeh25+56+9ir/C7JLl382sRkcA4ZOQHVDI7q2c2Dlf4cY0qA17k/s3j5U4/xlG3nDwxJjy9atW1EzCr+W7+cm5FJCg+qxPsbWpjffR9XNeT3tiRClek3ft7Jqs7NMQ6Uz6drz9+Bv7Z0M993yt2LwRsAN+qcLmtBIZwHaID9YprH/J6ge4F7c6PuYJR7/oTVShmYlMFIp9zq8QAiASy0gdtpmw8kRnOzdQXtjp0WFmkYKleqo2/KsXbjJ/wN4ge/xa8rmvsdug+cxi/f5lOmYEHTzXbSBeynh12deNlEbzNjVWd0nqE21Eg6dgR0DzEPSn3wYzMYdbtOBC/Lul8xmILNjBPPkq5TJdoeJN58UpfIzdVdVb8oLLvQyr87jdQBisWKkhEiBuc/P0r5TNQwur7+NW+W5DIybLOlxxaBxS37giM2o3xcrb0EygYLguBzMrkGSWc8ynDSotQDj+Rh2AS6QdjGoYCYf8F35K2Z2fZw17mfN17IguApV1aF9GCGSHMNjaOjE4wWsXrU78bj5rtTXexMRFpOUdQ/XrMlmMYi3VmQtK467z+XcVzog7d6bQCpAwNM+8P6hQacw5n9Fdunxzye2X+WdT8xlCtlNpvxSM8wspJlywNHgfd+kYTGrkfct3LrVX9CaVjWS1W4HgVPf7uDWld/nuY1mjDyhx5DCPJ+ESHL0kG8TLjfjls0FftujMmrOUz3T7wegLGDO3Q30583IPubx+iiuEp8RX5E9T/m316SS1SIsqZi6qUIvpdUTm87MpY7dbs6Zfx5l6s2YphLysM72tLoMY8XtHQBM4ZOdPvcD33qBo99cyYhmd59F1p8x6epqTVUwjDCz06MoSvqf6oyNbqH1mC6d3y2MsXezzsB4JYVrFqMkEwSETqNeipaIUbziI1KNfr+lzChkpNHPVzQUB3StmJe23suSdrOoIKjoBHK0VQNzZl1RV05KEVz90M385LkFBPqbxeMT69dw0ZtPMKrZ9XfO2msEioDZwyoJeNiA1qfd2IEiJcM3uM+ucPWinMfu3JhtO1QNGcaAuuyuHL0zzWs0uhqIPv99Z3ntueew5Hu/dNpqy1QvpKLsFR/Mk3c9xgmYum7a1PsdgEqmhJNxrvjLzxi9yYoxSekmV61/0zGNdFwj0boHny46yAF9aZZNkLYIDopKy5339ogzBzFjhG0TShK9LSg2CMHQKYj7bZ5+AwahxnuROdjyd0YC4YxiDWs/N40dzJ0ThjLi5ZcY9sgjjKuPULnQ9Vml0FGTcdLlHkbVPkBtkUiEGbNmmeCNvOL/duvq6hg7dmzOkcePOt73uz3UnpXczpSKk8ZQ8c2xBAcXo0S0HY7/ussuXf7FJBdT2//jx87cmhY4cwzgCyEZqGx+M38nEa+oedqPplW/bk2jYejaDmO4pbEeLpQ3cwW/4arYH/m1vAJDKiieOaRD7+CDBn9czWFqs1RH77aTYdgka525bVJx44fFPYMpScOgdnPdkpZDWf3PmxECThxzIlfNusoZK6Tg0G//AiHc+JuUNsDHlZgRpXb52bzdXsi6hDtfaJZdbvq1eZjapGTqzOlUNs7ltDda+NFScy6dMvlueivdHKuewz89ZdZgZ79PpEYQ6N4frbmCokQMAQwlR0zemtN/EH2bSwfXcGyt6XtKi2lz77EZOuuk++GcFyFk+jMFwTweYJ62tzsU+13cKVCb+W9YUfDNy5nvfKgIjrnD/LufW/BTGipleu1031C1rAytvJxyOw9enl1UlK9LHsDBl3yHWUcdT/9RoykPmrFZ3cZVaJYNNf3MfJv7z7kPmVRcwIBw3yQ+udp6ZoqiKIyfOp39DrqJSKTMWV5x0hiqzsvddtP+dKUhGVdoxoBEd8oXAyytLnB0l8xg9zvggAMIBnfQzeHfrfcufBMudItVh1cXMbIm9zPoN7yEGpuFbifdg1RGZ0btKxQj/cKgNiHEkUKIT4AGYD7wWsb6ciHEC9Z/uelw/gdFColAoqgqCTVlKUXbCf/PAvtfu+cO/vn/rsPwUC6nLMNetxDQQ60gXqY4/m0Gj+onTZ+wom0FyV7vxyBZ226yfCWVRlatvpYlSy4llTSD9uHqNlTVnGRq2/2gmbcfMwPzd3+jmruEvxLFsBSzUCRCkVT2Rngv4KkuL+wmJVyjpTsUoScYIeBx4AOhNNWT2nhIPY1/ipP5JycSJ4xm2SDrcdlDloqprA6MyboXLcJ0SLwVAtGaZVnjjlzqtn8JFW6gq9R05uM52mfZ8po4iG1lJmhuEzkUlSVxLYQBrFMbaR3uMoXU9F/Lck8fbjCrvL0BoCjuJJjoKQEEUgiSyQKWLnIr34eQ/S40U40idF/VfCAPxewP5U84JDkFRdF9gWdbbpCX0fRpdiu3nZGa8JasZXvyFgKYzKdcw0+5M+oaeoWFJhitIIOlJbaTrVABNJmiOE+LzAujf+JE+QAVOdjG/tnfTZoXdvrb0XRT6gSrJko3GT28bCkt481q+bT1/o5lBZcmbs3a/2zeZfOmSXy44Cg6O6s5lkc5eNvrzvoy3UwW1xklTO0qoE7PPV2HdND1ILGoaTDWyIacrd5yyT2c72sre0Hz1LxjRzVu5XwLMGkb/4ZUqLRYY6bK7IB8Q6EbBAjHCwiRIClCXCTu5Zdc66xrCnmM8+5hbF0/NOc5DPkMz/2/WXbp8c8ntk9qB4sV20JWDLZF2tCVBOLzOkRfumTbFY9zQgaoLVt+e+9S0hZASclT4W4nxcun913B6qX2zpVY+OegANuLTAO7hWq+K27jevFzZ31m0twWLwC6tmDLTrOmAYxmJRvFCJaJyTnXt1GJXp27WnnQQFefLxOTiROmJ1zA4oEjc45/URzGzXyX5Uxwlj0tjt3pcwXYbUbfVO5xwhhq9jtXTjvXS5POe7mYRFQUo6JnJfC9YgRhtwkv+JaFZYyhK2o5jkeQMavCzTL8dMO976ru7jfqYXJRMKjo7WbmmjUYxmd3htT1LgBgSLMb2FAw2J+XuWbTSmZ2+YFPIzpzs83ZQRyblUTNaNlmy6SGZiId/vZfYAarAob/PU4kCrPGBUj5EuY2k5iq6XlbX+9Ijv/InaKHtDUwsnkb5b0msCWXHZWvNdn27SPZvHkKsRxgPFsmYLIA1HVYQaI+gniDhauXu7dOBaCpaRiffHwYl6/x22OKkaYt7gIdlLj7Ptjg/JPl/Vwmb8h7vELd1eWKYWAYCuW08zvctvQjJs/+SlWT/Stlly7/fJK25jBNGk6rTQAjT9vEf4e8+dZUPph/sG9Z5re3zWob2NTby+bNm33rHn30UZSMAL3Xl+nW98tirblq3RY+Xn4T4MOXgAKKUBk40NTxqxiLUAezqdVN2HsB6AC9oWy/4AUOZbPVbtNuTzawwiwuE0J3mFgzJV8L5u5QmqJil13by8yci5nGyz6ztnQIiaDLLGOLNwEtpOHMpzZTWzpHorA32Hdhj/3ceieYtoSig5ajgn0iLuPK6uAW+rENKRQ+kXvzd3G6eR7Y55HJYmter6qkURQdwxBs2zYm7z0FKOvNDRLPJSUZBUVFeQDmXvEyrt8QuITT5N2+9batdgG3cSvnOfZIQOaOF1TEcrd7B1OP63naptavcwsNCqzn2doyCCFgyBDznkeb8rOsZYpqGBipEGV0sNfHLzNz0buMXbuYze9UcOya3K1M3xAHcA/n+1jwM6UgGUcgmPfsVq5+zs+iGyCZxeJe1WPQtnECOxKbeVYiEMBufMTo3rVZ46qDDQSC5tjimP97jseLaWwciR2rNPTs78D+dhq2j2bbe/1p2+ja5oFUts2veuynQAp03X2ng7LXx16RUAVPzMoGy30dZZce/2KSm6nNZCaQO2BqC0UKGDhuIsWVtT7AtzS6kIbEkJDeQaLK1kOZLbSGtwTp3xIGC5AcjXYhdbNI3D5SMk/MoMyy720dLlRzHrPBsuBnKg2l/XNFX0zqucSOKS5ceAgA91a7iehIKsHM9EiMjIRtTA0TpZBTqn5Fi6hBSJ2bPzLPM7DdLEjb5+OVDG7zA5xbImGk59tXuj3+UqyH38tLOJu7fNuUyNwFrqHoB7QPnIsi19DhKbIpsjLH3hhkQBWkU6ZfI9J+nTNh+0aefcPUcbu3pNmnKY0AAtoQh6WtSylk/4F+H27FIDf+WyYLrBnXPY+bz9iN0w7bnfZkI8s73mdAhUJES0OONnVeeW3CUHpiLSw1liEUwT5nnE9pjfvs92I+I9nA9CGVrP/VYdSVRUwmsByS0vzxICWHLXLkiw/RL9GUtbywtAw9lQ1ECBUNpmz9UMrv9OuFmu99l1PPO9IBi8l0Apky9VxVT8z5Risq5jrbpOv9BVC2jG5oR6g1KAEXwJ0JlhpScAClpbsxZ47ZwWb07FoaizayuP8brCuZwoXnnkWhxSZUNmogiieBPbSyANUqWsjVdnXI5KnmtRb2nag/65l/5FweEIJDt7p2qW0DntS/giNqygj060dk8mTqugqY3OXG0w6/4kqmHHgYnk+kT1DbTknRzhd6Zd7jdcXrcrJDe0UJqhRMrnbau/6vyi5d/uVIMAc4aBsDHZtTd9PogJ/lSiJoW5ndRWFH4n3D9QxdnkbDMFTHtyuK546lH5KYwt68QSldTJWLGMgWDF1jcLrMPVdFoSHqt8ftYztXEe9PV8rOhZlrkx6mreaYmdNtAn47+2EumnwZRjrsi2d4ZdiUwQQjru5S2y0/2mMexSsEWrKElzsKfLGHZMTu3iayooHBoMvUJhSBIjXq2uMcvTVFa10vVVXzoGgG+0uzo4oU2bpEVYSDJevUy9A6D+eSfUY790PNFbe2/PISPcaPR9S574sVixaZfnu4FAa7Xc7uO2cW3zkwO877Gbqgfm7RrecZynhWr31vXvbgkfvDJfNh6jc/20Gqs3EKqPnjz4Vl5ez1zbNQFNVhm7Nr1b3tR/9xxD+4etbV+Y8b2Pk86rUj6phdmh1DV5TPX/xdMK2G8MiyPGvt+y05trac4DuNqC0J1DzfTHGlGSOoHjwUgD322INrrrkm59j/Bjnuyhl846xxgAns2xmx7Y65c+dy8MEHf6XA6l/oUxVCXA08DkwFB5XluzopZTsQAw4AjmeXALZzLQFB74So1RbSorT+j56ZK4bHYE7GzCCXYZgBWZHJk2qJ3X408x1X7YCxZ0VHooN7lt6DHuhhmdUqQo33Okwy6YCGMmwGUgh6Rk0hZbV8BHhj+T8wRJq05Xx4gWNOojIgmXL+So7t7w/0i7JuX3L9wTkHcdVe4/Dmgaft/RoD5jbSFTHty5fEodzG5aiWf+ilVd+ReBPseo5k+8wJ7zt/h4k7AKEe+naabFknspWwLVIoxIIhCmSIjkGuHf1RzSQeEGf7xgZJ+BKvXsdfsVH5tlO6g2T0jVyJouhsYqizLEDuCuYKWonPuAVFyZ1gL6GDaMcADOOzfxnBguxkdmabrYBwAxnhsKeaW77q/L2N/K3hMiVMPCv4D2ZVuPioH0fxuO9enLswu51XKO03NDoNF9TmTbZ7kxX2u6WSZnftTd/2A2NbGcImtm4dRzxewupVe9C4dSSD17iMck+/Yxq0AsE8phGSue+37pkXrv3gUw5970O6kjvnLHSKcqel6FT5EUXSfcfqpJvwPmPBGxy9ZDWDl57BXW2/5vx3TOM30NhIKZ38Rn6bi6xWKPlETaoEPUDKFWIiLZ+YybpuT55S6x5G48ZsRj+A4d2rci7/OskuPf75xWHfsP5wnEdLPxpqfGeKdP4t4pjunkDUk+J4dL1vJrk7v/k9jm882NqHOz8X9nPBtdj0730wUIAJ+kuRZo2y3alO98qico3WAhMA1ZmjJXCr2HHSsVBGPxOozZtEziVxEeH7SjZIGCBSHuNJXFDazoCf54s9+IX4GZANM/ymvHeH2+9IbhL/x2scYO3vr85yjTTDWecbmw/oZEuMAicBbMsBvEDAGEn/V2+ioNtMWNp2mJ52J1bNyB+gt4EWYxJDd3A12RJf5Aaz912czXiqixQjPa/06VsXc+TGFhJatvNu2412qzYvAMRbXLKtazlquoDb5NnsJV0guDfoXb9lPD2dtSST2e+ARsq3v4MxGXu7KeIlcZhvbK00WwmUpPMz0oD//trV3oe3FHHg8vc5nmyWl3ytybq7TTaFvlgcDuR5rtWv4ZHEY4C/tWymjNb+4Py99b2Lrb8E0WgFRVv3dNadvzZB2kix2TtBtrr2SB1b+YO8iMN5gqQPBJDBFuFRVYo0MKSVkPDcvnD5AP4XZJcu//yStt5DzdBRPM6goX524O2XJel0N9FoJvup/9uzg4zvvvU2d999N0YGg4Sa0X7UbhkN0GJcgj7/dki6c/yrkydxq3IGAHrAox/0NEcOupSeHnPO/5n4BdsG/oxb5rhFZWtEbpYHWyRwvziXH4gbeZqjuEN8C4DRw8wWWoqSG9Q2MeXqaC8DI5g66rmSg/kAMyGaku48XxrLBl2lPTaKFApbInW8ph+A1730zjcRYo5fnHZAbdnzXyzUd9DVrmi/Sfyf+dtQsgDRg+VG6jwM2qvD6yiywL2/GjHOWW4DxXTrPPaSrxORUcoxwRGKqlNa2oiiSNCDWS1ZvVLcR3vxTJmEafONTq3hZnk+o1jNvI5s9jWAEe2bKJJdDgudzXaXyWJe4ikAa39hD+de78srOfc7pCc/U21MDaHnwaDqvdkAy44OP3ND88bR9JPbqE73cIX8Td7jgAnG6lqgs/TxCURXR5j70VsE9DTSUBg7fzEXy5uYI9/J2u4VcTD1YohvWU3aBQ5ohs5QvYZESzFKl//8+m3qQXT62c4G67Dt0wNZsXwvrpLX5z3fzPbjABP0bL89Eu5mwgTTxpEb/HOP9KBitK72vEUJ8WW7UVS/kaYlZWx+0QXGSUOhoscfG1E981U4DdUxV1cboewk4YcTs1uofN1klx7/4mI4vrm7TCJAKMg+ukYAGIaOUBQMXfpA36neF5z2o8kd5HGcVsNCEAjE2Gvv+ykuaWLV7vtw0IJapMWQUhRPUaiv5oUJs/nN7jPo0eDmMbl1iV20EieCAejCnDe8/q63E0JdTwYg6TPmnuyYYo/lI6yMuEnRmRtWoObwAyrFQG7ATXAexyPs3mre76OXTuDKJV2c89iNBAyd4R52sf02bUPXNX4gf8pv5LcJetggtHSa6LqBWbZBaSy7Y8zxyRu5ZMUjcMgWWgr9RTRbtppAKSVhEGsNsf7jQWiKQknlmxQor6Jl0skBtQlJv/oruXiNq3eEJ8stgmGali9yfm+u6WXBeLdoucBqVT6j0r3W3cdUM2rGbFYWmbH7imILWG/sHEhpynBzTt3tsKP45umnM3XqVC677DL2v+yPnPa93/iSjKqEfZdvon+7HwzerlVlgTREhj0yauMKcokWDJGOZxf6qVqAsRN/SaAx94sme8xYt0xGkTbg0tApCPsL8weEjibx6b3O7zN/58ZfRo5r5lh9MbPrH3aWVQ/2b19YWMC5555LWVkZAJGiIGXHBWhsOoruUA1FRUVOKkoNKD4mnnAo4IDaBnT5baPvPfwMs485iQMuuIwJ+/g7BGXKQ8WWrxtLc9Ya916pquCnSz2/dSN3UnjPK3wEQeX9B/CNcy8mFnPPKRzeuQ4pPvEeqmjnmKtyyfFjjqe6IH887ststfbfLP9KXS6EKBBCHCKE+JEQ4p9CiE1CCGn9d91O7qNWCHGDEGKVECImhGgTQrwthDhPfJXQCkAwB9AkLQI+UJt3BvfG3D5L+1GveLfTM0BRaTQ+Kp1CTJggnExQtC0F0tXPdtxbNzRKdb9f5s1NLl2yH4GGGQCkrA5pAsnGdtMmtpnaDKHyQflMlldO4DEKuYZeTv/2LA4eO96Bm/VVWO99wlp3t7Vvd+FH+2zh13V306X58wSpApupLXvfQdUuFIPakDnHlBWUMOCXezL5sgMBCCgBzubP3CdP4LiJc7P2ATBy9BjnfBQh2GOky/yak1PNZvPKjGXaNtwOwLVDqwq5cJ5VkO69rH8DMUHaAbVlFEFUF/HoRbtz3REZ7Tlrxn52BrCCCjjuL+7vi97ZIYuaIxnvvsPUBoypGMOp407Nv+1nOM+LB9fw5PRRWcsV5V8Th7O/DWkxvyrRvm2wAWPGccr1v2PWMSf4ls+c8TjTp2fH3f8bRNUsXMdO8mnZOcRBgwY5hQNfFfnc6VYhxBzgF0Aa+A5QBeSObsEDmFPEAXnW/8+JFBIFE8Wslmuohpep7ashhqGjWe0Vk7Fea5mlXK2kfTSt8+ILzznb2KA2XyQBGJioRZHChxhv7G1CIEgH3SBXaPtaWPGU87tdiyO1AOtrB9E5yD/ReZPidguLYDBKSYkFzim0QED9/UHU1KRlLCqK0VMr6dd/tXvupJEIPmKWw54RU90E5TpGOlWl3vZOO5K0CDhVe7mS/l7gTYSYU73+d07f6WPkkkOkycwWDUZQAD3YTRM1PMI3WYf/XpbLVqppRnr6zXgT9DJlnfdOKqcuSmnVivmN+DEAte1t9IjcLR4DpEiXbSQY6s0CnNnrgzKAni9abUmBjDJV+ntavyX2yxpnt4W1JR/d+f685Px9ZwYbYF8SIk4gR2Kmp6sKECxfNo+gFWA+JPkSw3OQnGUU0bHyowm0rDcNv0S3y3rjM7itd0vBYNv757PfCs+9iGm8/dappNNmgCUeL2b9upkonu0jcT9Q0xvE8Yo3CD2wG8JpnRm9+dsCDOvxg0qbrITM3KUBX43HzzyBsNN7ZrBf4QGUbtuLqR9eQlHSvF+dW0poW1tKw0fTfSwBP5Y/yjquSAezWrXUp8qIqvB8f/ddSivQrzN3hU1o2m45l39dZJce/2Jig6NtsJfitEOwPmCp/Puph/OIM7dmzC3pltyBS1u6isvokKZO8oJ4Bu19C4FCO2huBRXygNqGdnQTSiVZUV7Io+VbeTO4nLjSdxvNrhygtp2RpcGJvMaBOz0+FwB5Z+Wywht5RLjO3LfEnTu97cb48KxAy3Q+yjM6W0YlV+dd957V3WAsLpNcV1t2AFJFZ/myHJVglsSIZLF+nciDRAJllOiljI+bz8hp9eMBUPQFagtabVvtgH9f0r/JH4z3MnvkOkaifQjBtKtUj2ltosIoIOKpLC/rMRPpJbFepBQoQme3GU9SW7s+a38A0YRpU5bSxTxPka23fcCGDbux5MPjSCazA82ZARgb1H6R+GvWWBvYf0rbIznPxZaqRlc32S1SpqSHIrYn2bL2LGfdfctPBCCt577Xtl3V1ywlgIrWGF0Ww3GmlXbXYrdtb6HRw0Ufvcm8Jb3m/OeRgKfa7rx1SVIySVL1nFezX/WI5ggdG2cjFvsrDA97xb03j3uSGwpu4l3Lk1j5usouXf7FxGZqC0oDoQiO3m76tWntq5acyQ1q6+hop6pqE42NfmbNTKY2b0GNLgQfpzTa8rCg6QFz7PMczoZ+GooWcdp12lLfP09bh1z789gHfxdnOH/bhTqKYuQEtZ3b7bJ7XcoffOtaqOJpcSw3i+8B0BZz2SdyMbX1xit45fVWzjVuB+Cv1afzF+0ifh64zhljA8nKZBs/4YdZoLbM5AbA1nDfCUIpBP098YaECGWxqBgZs3Bd3SqKc7ChrWUU7ZShI6hp3sZF3MJdnEHIiiUUFHRQWtps3gM9wkE8h8jBTlQU72Voy/Y+z9srVQ29nPb+C1yx+i0qLADd1M7crU0PXfkus3AL9mwwZSa721684fydaivlHO5ggNzi29Yrh2xYz+/kZRwls5lQ7hlxEqIgt92Ri7HGBmgCDHk3QTxezCkfvcRd9zzHTObn3I8tqmGg9kRJN5n31asTtfZW9uQtvsWNzrK9ZXYbdzCZzo/ufJJT3zFZiE5uqWN22ozPKGhM2OTe30I9gRr1x1EEUBooRNcDznubS+zv3puwUmU2oDEQTFBUZMbM3hzut429bIa6FBiG+x1MSpoFYCXzYfitSxi4aQMjGtupqvK0UJMqw1tc0KZ9/iUp8+4F0rBHwmVMDm3PZjxOfc0ZV3fp8S9LLJ/EcN930zTcGVCbgaKqGIYks9GosNqPpnaQ6LTBZVJRKLW6bwwYYPrazeU19Bab7GflgWomle/Jxqr+dETCXDcxN1Dluk+7CafM+f1uLmDWQcWgmbrSC2qLe0Bttn9yVNJsa5aLYbQvsfW1LgQ9HtbVAfFtaNJAlQpHfPoOqmduTSthVgk3AesF02oSjq1PE7TYqUotltDy5iepiiVIp4NMZDED2ErQ469peoqWFj8QGEC0Zeu085cs5sqRowmoAdZWfsLG8qXOuvErX2f/t59m5qfvsuofw9m8qA5NFQSCbVQEb6SozJ1b7Xny1mALht7gi2y0BFyfeEB1mfP3jFMv4LXdmn3O1EjdtAumlG2lJW0xxqgKQU2hNWDpH820v/SdaLEFEPS0da+uruboo4+mqqoKqkZBsZ9ds+bqqxh86aUUJP12VVIJklD9c2lZlz9XkoupDCAQCtG8eWPWclULUDhnNqHxJgB/zMZ17L7YZe422t+j56UfQCoKugXskpKZs55kzz3cAjUh0r4Ma9Ug99mXDupl6LQmZj7n+s5DJk/lnD/cQf9ii6k2RwHbvLrD0aNjCGSw2GsBxc/gI4QDais98kiGPfG4b7yqaUze/+AdtPXEeQeEhDfWt1FoJcuDquKz8nKx9QImC891pv6dfcyJzmIb1LbXXntx6KGH9n0OOaT2ezMo2tsq0v+M7YhtGTVqFNfufi1KHgqji+98kIvvfPBz7fvrJP8GXT4LeA64HjgGGNz38Kzz2w1YBnwXGG2dZzGwJ3An8Lzw9qf8D0sgTyzdbT8qfCGniR4czI5ahOYTr27NLGbS0Xi2v/u4hHSLUr3i44BRzO/d0DUCnuXfeOdp3zbt7QMY3jQUgHe6mulRC+nUSpxIopdt9sOyGbxaYsZ83yKNptkgaeu8dhKUJbSxaJF9HJNnU0IhVWDwRml2XHrPcCP7FGicVObqooLSMsbsvpdvji2uCDNubn+OuHQaQhHOuWiKxrakQMXgoulnZ+0f4KQTjuc73/kOF+8zkvvPncXgwYOZOHEihx+0P8qoHJ+JPSdn2HfSZmrbGaCtAuHxlVSd5WG//jfkcNJ5mNoAZg6t4Kw9hmUt/1wyyYOZ7bfzsZtjrrqWsfvsRyxk3ttgHwxvOyu/P3EKPzps3I4H/gtl7O57M3rOnux5kom3GFSx465jdaPHZun/kpLJlJd9vo5y/2mxmWp3lqntoIMOYubMmYwalQ0+/E/LF8FPXW79+ysp5U1SyuySGVds2qBpX+B4XyuRwmRGEAgGTp8GUvHQpX8+Q/Pziq7rPP/883R1+ZkhDF0nVGgi0JNxq3WBYToNigVeO2rhWs4MuSxHelExvYPHZOmAn2y6lNObjvQ5ewJBQKp8UF6Abr2KTTUhFna5CSsVha7CEl6cOIdXJrqIUEVJo0dc29A0PCSFhR3uAQbnBp4ly6I8POsbPDD2GEaNcgOXybm/ZSPDuFFcxX2cC/jZysLEnSTqZwG1ASxjouc8/eIFtYWIEydCI7UsFzuvcHJJWco0nqKhCK2lq7iPc/iO+BNPiuNYi8vudrb8M7dwAWV00N7sMpLFhTu5K+m+lfox61/0OUjjWEaPx7Gcs+CFXJuZ+7YsqDFj3iNXizyNNMlUN2kPC8zx8m/O34XSDOT+mB87Lav6krP5s++3zDhmLGaCxrqaM/qv55E66e/tXsfWPCNNaW0dSLTdBJCJQIzOMQ846wakzXd6YqffKNsQHsQddSYjUGncw0TgAWRUWi1Ne94/ke6tuzG6qZ79LWBbaSxKrul+StQMIJd3NGetq0pKvrUqBy2wJ45kV2pO7lnOLfK8rLFCGsTT5jdkt51psUBtbZ0NvrER3Oq1QIZyVazfRTX7MmXun+ntLfW5KCPJAfBIBZ0kjy1tmuDX48J8VOl+hykFolVhND1HAmxm7gqSr5Hs0uNfQOwpz8awqbbisxlLpZKX+vs/JZktA/TF9+cdO29/t4rH5JXNYEkKdznrAIw8oLbKWJy0qvLL3Qbz+1kT6YgUsQOVQidlfQ/II9vUATwuTtjxQEt2FtR2qnjsc51PPlmpjs8CAdpMK7kkHvdSckuuTP6/HR7DC67OBbRWSdPamj8ONplFPvsEzCRRofVOX7g2wREfLmBUk1kR39ZeRzqt0Rstxe7wfr68lR+n/aDj1lbTzghkAKlzSVGveXzVBit5dEMgoLH7uiVc1vV7ADa/eQU93dUoadduK2+awkCjkn1WucDr3dYu56I3nyCkpzEMhUAwTkGB+S4bhmDVyj1IpVygx5qpbiDA26K9uGcA897fzJx31zP35TdR02FisVJWL9udpvphVEpTr2a+6rlYU2yxg2911dmtwbziBaRPXLOSM+Lz0FB5Mz2S9zwMuavbzcTwbsqyzF0ALrteZbA453qABQuOZuXKPUk5uFi/LXF4uwuMDcoUvdsL2Xt5diV/oNC14VQgpceJqW4STm0x6P/pxc7v7Q2j2P7hmWwv3M7dwqwUDSaTjF/rMjfJkD+QEAyYxw2t+qqUB/3bZJcu/wJim7UKEkURlKVMvZD+ijAONEQtezkjkeS2KBGMG/8Wy1d8i1svepXuNvM7UBX/vJ/G/QZ7ytbw18pj8h7TCJn2/wPibB7Yu4LdDyzmzfDen+m8x2zf5PydD2xu65hcTG0BmaSiuMFp2VxBq2+9zVQeknH+tPYnbJFDnXWhVPY8m0alLBmkNO4H8m1W3e0CpJgl3+MWzmcQW5xzeqdsDhKQOaqG3w/v2FcYOWqB83dCDaJlMLMYqKxZ47ZX7NdvHZk+cWUihS4CfMJMdEXN6bdUVro+aVAPU0iUOakPs8adNv8lQh7g38nyfn4kf8x+VluYTOlq7UdRMk6iYRJD3/0Fa1btS2HUz/YVScY5/qPXOHbbJJ8/bj9jL/OrInUn3iUNQFeYzKf8hisYx3KuWfWHrHNQ0gH6s50T+Rs/MK7zrWsWtcTwg0KKpKnXvcVYbW11lKjTSaXcGEdAGoxeuYrxb66la0vfLd4B1EyQoEyDCNEvNYW9C1yA4xkr/sm5mx9gCguz9nG7PIsbuZTR8fVMDszng1dWsE+rgoJAERolnVs48TX3nSmUccotFveCpHk/G5UORKSXrq5qimP5iwQG9DeLxrzJPV0395Gvjd8TRgaAzMPUtqpwpK9V6C/eG8ijH66n+mGFkoO+wYZx+7DooMs44xaXGcAwFEY1bqEkJfnOihhF8V4iyQT3vR/lZ4tj7FGoUuqZb9f2HEG4Oszsxr5BSF8z2aXHvwSxC84MHyhNAEpWy+1MkbqOoihWkicD1CZsUFvfx/8Y0y41hHAKLYSQhEI9/PXEy0hFzNibkAadwp0TNxfkdoz3aOwhYHVJWCHMeHKw0GQuSXl0ug1q21u+ZochCMg0itQxdhI0ZYvN1PbW6Kk8MOcgd7m1Hw2FY5rLOOkjt6vFqgI/6Dbd7u+CoAoNRUoGrHmXQLcJokoEdRB+0GzAo7vVtO506viu/JWzPJjKLowr0pMIReOgoQeR0hK8MNYtNFOkZPqy+Wh6mqXFE3im9hACqgIDzAIhoWQDZusrwkysnsjpI6/hj5oJWOgR7rjKOjdmXl1e7Dh73zzvEnaP70WNLCUw0GQGm9+j80qXeV0BVZAW5v016naDg37JwJlHZh0/l4jPQP9fedZZVF10kU//gb9tnS0nP3U3xz2/Y7aRaQcfkXN5KmHai9LSTbf/+kf88k+/c9aHx49F9pr2m83UphSVoGmFhEJW0d10s9ghH95KFWYkKlPK+7sMn0oORp6pg8o4a+5Qfn/iVPP3/marPi2oZjHxDB5sxkTGTZ5MeKzJPjx6971yn1AeERaAUWmM0YB0rJ5ghd8+yXwumfK9h59hz5PPyFq+zz77fC6mtkBVhMiEne80lEtOOeWUPtcXlJQS3kF71v8R+Xfo8nbgVeC3wCmYLU53KFab02eASmAlMFNKWQwUApcBKeAgyKgi+g+Kd0rYzXDtYjsu3T7lLySGuMUjBdVuDKqLEmKhCHqi77nTm2eEjE5bOZjaMs/w91yWtU/N84lLu6uJrhG0lg/dvJqi3uzipUMaDAIft9DaGOSewWeQVgKONZKZt/RK0AapWJNoLuzpkOdMHycUcn0VNTDZaussWP3CKG5vDiEQPHfMczxwqJunvPugu/nNnj/k77MnctAcN/42cuYcDr/iKl/rRqEI9jtjHNWD/PHFlJHi1uYw74q984JjA4EApaWlXHXwWEbVFqNpGscffzyVu5+KMtyMQ4xkA9+60ALF2fZNJuOpXfy8E6B+IQRVZ4wnPKaC4xKzOSk+F2GB9C655BIuv/zyHezBFa3WzCGLnSjEycfU9lWR2mEj2Pe8ixzV62Vq+7xy7PSBnLfX8B0P/BdKIBzmiO9cTVGFqROfuOT/s3feYXJT1/v/XGn6zPbevOveewM33MAUm256770ZQgJJgJCEJBBIL0AIISQ/yDcQSAg99F5tDMa99759d4ru748rjaQpuzYuGNj3efbZGelKutJIOvee8573jOfJy8d/qX3a39A9llrdrrXPzc3lqKOOwuP58qpYZMOePD3Wr/6bzhpKKbcCzUDmGm/fMEgpQShDLDSNoC+EFMJWu9jPpLaVK1fy7rvv8u9//9u1vGHLZgIRZYhiZnZIwiS1WUptnzap5UUBNbGLFxaRCOe4lNrqRQtP+z5OOj+F3o6oeB8jsIlt/u7MGdiNxzg52T6q2dlCQgriZjZRfVAFdWOazu8mnsiao+Yl28XxUNNtPoMG2wOaXr3SnbgAt3BHxuXl5ctoQR3jcwbyK+awAXui5KcN3WSAd1Z+NBJ1S7XeJW7mOY7IWH7U61CTspTaNlHR4f4tTI1mLtEBkG8O3iK1a+nd522ec5S5cpY2DZuZ081N+chEZqMf6qT0Z9maVqYutIPGmyjnxjzb+OuObKRBci4AMza/xGz5d1c5kkz3vowLYtEG4o6SnMdhZ2lfzi+4Uf4A7c22XcrGKG7dmXoE17dP5h1Gc3M+29bVdbovgD4tbhJbv/ZFtLcHuVT+MssWGo2mak4cbzKDWsgEt+74Gf/832YmfPiWa4sPh46nKWjWi29S99CYhg/YuMIu93Mij3D2srepW+NDmM9p9y3rmTy/hfOedGeBWFjdpnHFA7dz9j9/l3H9Y4XPpC1r9+pgTsTXNysyWTzhI4id9X2nvCr5ucWnHO19WIRuxJOlc7SYO0tcb7OVmXwp8/yQeV/m5NfQu6qEFTkrAbha3skP5fWu0mqa+YzmtsVczxbADr9gS8B9jzS3byfe20ekzXYsHrbkTaYuep/GaOckya84uuz4HiA5aTS/W5MzJ/lrV7Ok9jWsXqQOXJvbmyh/eS5/XLM5rcRzs8fuewuhpP0DuJg/UzD195QMuRdp7ASyK7WFYlGXQ+CRMdOJdTB502UsTVEzE+6UV3baxkKOrOc+eUba8pXzxmZo3fm+9hQ66dcrQDqJGGDxooP54P1j7XaBRkLhzvvgJE9lKjWarSQlQH68mcN5Ks2iVn98DT5zYcCAa/7+ALp5U8WiId5+61Q+/PBoxi1eQNXOLdSs2c7Wt2w/XfCVH7B8mZLVj+zsQ/uCyR2eg0AQWfQxU7ar147uILXpEoauXcaQ6Fy1wNBpMUCL287eYNyHQFDSVM/w1UpNJOFwekup4fXa113TJJs392DlimHJZedPUwEoLR5wjVH6L/gX5avepnbN+wRaWnk5WsTyxj5on4TY1ljN7dzIGUsfZ+WKYaxZbWf+ZSIYpsL5293wSTOHfKyICpbizpi+9hizZVgAn2NsuXKb/bs2RtWYtkqPsXHKMO7vm8cN8ocAbN1anSzBVhDOrozY3paDlDqvrFJjnUzjrN99fjvTWxYiaiewSGYu1x6a6TYdCeLu8gXtbeRuGku/z+7nnXdOYOeOSoT0cMXYyzh01FDOe+mxtIxW3Vvj+r5pU09Wrx5E5HmNfuEAQ3P23PnyFUGXLd8DJOffUtnsYLsixh4opLbT/6sUQVOfPUuIxqXA5G9k6TyliJSq1BZzlioL1LMqnj0DWPrS31N/957lIrN0htLG7Ry5Utmqv4j0xBewE5uElkizUx5iSCmYw0+4Uv7clcjjRLsI8EbvoWzOtRPOtAzkBcN83/ji2QlAzYTJoz55RS1S25JITzbmFmJkCAh3Bik0nsWeg8d0D94U9bCE9NLS7H4P92AZoXgLoahqO2uuIkc9IC4hrutE2tLP0VJCBdBJ3iAuVLeo7ZzKp7N4gv4sYBTvkQmW8p1E4m+u4rehd/l1qa3IEZAtnP32sxQ3NxCMSdec0FLNLnXE3JwkC2lWKxDmvbV+fR+2b6xL64Nh+gGkFIQyqNi14X7fB8xkKafqzMB3r2bUBHfw/v/0Ixk+dy69li1jc476vf8gz+bb8raM18Iq1z1slUpE8yfaaQzWMnDp/yiaOiXZLrRZo6Jpa9r2J7yzM0n6M6SGv99UdIf/RRc6Iz+5m0nv/Y7BSxcCEJHtrPUrAnlFm/pd20WClfoWEgkfg99WpW2nb4wl58EWKsrd5WsMKdj4uTIZiSyu4EYDtsUFn7eaQTLHO8ZAJEkoodc0QtE8um8vwRdro/Ln9/CdX93Grd851VVazTB08tpaeOmlJk5fHeeMd59HlwbVrZIjN8Qp8br7sR2DIef342/HDaV0i3qfHf7+mxn7+jVClx3fC7DGlTJlmRA6UnY8/jYSBiKp1GY/k5qnFoGaQ8ezTF8tUtmL4gjzmM6GkrLyZa5l20UD73ntBJZGkZ4MAtAiovhSCMzNpn1ulfY7zyp7Oop3kyevy0Tmcl2dwJqfrih2315Rk9SlozMkUesi5nyY4/aNN69wz68TMo6QoLWuRXf43Ky0OQtO2+2JtSffNSMdauYlOenEGb8RBU1nUvUkLu3+EIn2EvztrYRSSpG/kz+WHb5Cpa5/6A/gwpdod1RmsVBWmIcmNLZ6d9JmVocRDrtVVG0nhekee1xQmJ/HxbQxgQbKrhgOU75Lhe9jhg5SJTj9up5UzpNCh4MvpyjLXCW32O0LiWcg63cGLcX+x8wxTPuip2nZrFRRIy0NTI927leo7NOPg05IJza1t6g5qdGYbpcBii66kKIJFeTWtoBZqk/LdZPiOfrXMPW7ZNMO14TMqpxj2adMFV90TXDr0QOpKVS/8ZhZPbj8D1PRPRreCvv+FkJQWlrKrbfeSp8+KmFizqNPMeuaGzMeMxWTCtQ9KWIS/0sb8Cx2i0XkT6jGV2sTP/VEYreUgI4//ngGDhyYVJOzcOFvH+Ci3z24azuxhoRfMNSoHaDEiwMQ+9qWvy6lLJRSTpdSfktK+QhkcSKm43qgHFX29EgpVZkjKWVUSvlb4Baz3UVCiD5Z9rFfYThvWEeChVUpxUCjtfd/M277A/FjfnPuzSz8Rw9q3v8OACupS0uCcSazAq6YrRF3x6wyiZRkgu7st1nNwjA8+Izs7ysADYG+td31JrRa7ugxllnf+xlBb7p/wmuRVExfqZbh/RLq0ROA4cMepCBfCcZEG8uwSPwtDTm0SoEQgprcGnrm9UxuO7p8tE1qcg2w1D8hBOeOr+MfFx+c8bwAmmJNtBiChH+3xAXTUMROikrNR8YaV6XM+5NKbbsZi6noX0sOQYTpLy4tLaWgoKCTrWxU/+qXVNxxB94Kdzz/hWsn8cA5o1zLEua1y6TUtrcxa9YsLrzwwt3ezuNI5tsbpLbdhabt+2MWRfwMrcnf58c5kKB53CTYrzL2ZGRSCjSahnhX0A4cMDKmXyqkVEptJqkt4AkgpU1qE/v5vjLMCamUEiPFyeo3sy1eeeh+Hv3hldRvUYocQncbjdsjp7CGGoTVecd7OWY6hJtox0hIag65h74T70ULbMeIqcH9CjKzdXUEeNWL1Lo+LT41CPm7ODvZLo6Xurp56TvIgG3CniCmlv+yyqduEhW8K8YRdZRl8RElmFCDmu2imI5wyKp0Qt1fOY94hqC/nyj9pZJID9BKG0GiZuadR9qT18NlOjGpd3RJ2rIj5ZMAVLWq3/J/kSlppTtjjvOySG3hyE5X+VEnwgkdTbqN7fe3/4DfyPOT351OiGUpY2CnxPZsHuHPiVMYvWU+x/KYa8DmzzAeN+IaCX+IWCzA9U0/5Ub5A9f6bqxiCPPY+mlh2u+ZEcKL4TiX9pTyo9FoiI8+nIXR2nkW1O/eb+Gobe4AQF6sgU/nT6Nqqe1w6bdhJZfOt48TMqX168lPktry2YmhJVg99w74zE0wdaL3qgKuW7GGwfPWuYh+HuL0XhJGAGM+uIMey3Mo3jqYiQva6LFqVeadGTqBaCveDGV6ABr0hrRlzQGlighgbDFJAnEvfofSWgXrKJGbOGHbEwzcqEq6VbKWUKKVbahnp2rrTtd+NcM+F2/KO7Bfcx7hbUUUbpiH+OUQegvTMcE7dEc5iaaZ6gIzeJq/yROYefYcPCvUuyNH1uNNGLzdzc9mv/s+bvR72ebNR7TZ776qTTvps3EdzTE3OfVriC47vgeQKR+s+YjUbDt44Pl/3A/XG5vV9zuXb0hmlGeCRfi20CRyuVT7M0X93ieIun0y2TeAcDT9/aKHMzs+AUrZTL3oePJ4unywQ1JWKgw0QrSSY6h3WrU0yyI3dF4CMxXTHaWpM0F0Ut4G4EHfubzAEbt0vKamQqTUWL16EIYh0E2iwpwlv+MOeV3W7Zyl5jKVdbMCHcd99Cpjl7uVvHLjzRndyuFtQwhogmiijUdX/BStrZ785pq0dkXNDZz69qusXzEYKR3B63gw+d2Pl+iGATSuHsW775zg2r7h43OofftWhNAQRgKP2ZtevZxy5e57WUqNWLwNPW7fq4vrbTVeqwRZu8/v2Ebg9aSPOzZutKW1B1ao5I66N39M7aenJZfnNtqk57jQWRzI4TVvHoRCbN1Sx+L3JhNZp7FmzWBWrhxh92MXlNqcv9eY7RK/VM9DoOlFThd/paK3TWg/pOF92pDcRxv5IS/bWuyXTlMsh/vnn4HMV8kchxXnMYyPice9fL5gSvK3KKtUr/UZm9/itndsov7/++T65Od8c65Qa9rcJPy5HL/5RR5+/2IIFRDK8h4JltjZmg3RbSyPr3bfY+Z7wmPkMfvEC+imj0UgqMgvwxuJ8KPi/xBsdzsWR334U9f3eNzP6uVDEXHBK2P68dwod+nSrzG6bPlegBCg6YKAqfYoNfHFoz97EZtbrVLfKeVHzSco7nA4FvujvL/oV4TD29E1ty1yKrW1CIOYP/stEMOb0d2e6vhPhd9R1jCXBoKic+e/399MwN+c9m5UNkzQnwUcxFuZN86CmK6OO0R+xMFRRYbRzYC8N5H+jvpo0WE8y1E0i5zkvBjc5aPjugdDz05qmyN/TDieed7wV3Fe8nNuW4trXlwrl3N59H7ypTuwHqGJ76z8BUM3qeQvb9SeR27ML6agcSfLnxnE0v9kDg4UJMwS4eZlnbUuxsv/a+SfbzTTd0NLkpAQknafi3C/QnpuXsvByz6lot5UWXGskw61s4lJsQmFgIvUpoLYOTRx86o70/opzQCPNMc2VmnL2q0b6BW1SR+GWUZbGgItg1zSKtwkTetccmM2geKfw95OlqKJxdT9/27uwfy9z3RAKSs8s66GTe/OYtV8O/jQs3EFuc2m8lvjTmq2NZDrt3+v/kdMpfnv/0fZObZvSvVZp8ChMDgq/g4DVhlJP8Sq0Fryh05ho26rJmxpW8OA2Rvoe8KGJIEuKKNEfer4+bH0JzMvLnj4zUau+9hdAknDkdSCoD3u48IXfolsUz6OuOFj1tw36PVuqpqr4PYNQd5pNn1wDrtumHt94/XTGH6mnfzmCQcRWTK4ZUo58kOiAxgXS4+XPrNiGh/NP4d7aCPo1Yn4PUmS0glv/C+t/dcMXXZ8L8CRVpayTEOSTgR2wjASaJqONCQipTS3hgr7xrMQUVKTprWA4SDbkDbHlkh8AdvWZDBLADSKVrwppQq3FKlxeKujqkazUGNsnURSZE6XCVdCWkfoJRdxlVTqWtZ83kg51zYRMI+hnudwtI1jPn6NSCz9GLrjhD7a9j9eXP8QxbWN/PkwjcU19nk732ZN69020BOPEvr8E1LRb8iwtGV+I5ZUbAl7CmhZPoeb//Z9Lvnrz1ztrFJyccMA3QtVI4mnjHZCyz4lLy+Cbu7vY029e1+U9nxx5FHH2P302eMCvyfFNskERxf+gOH9FKnb59GSyvadBRMDEbf6XeILkNpS58qWTYl+/gTxnXbpz8JRHZfQsshseso7fuxxJzFgoiJzG02ZfTu+mhpKD6tB9xtIs/yor3t6iWkQHSi1GZmlh1zYvfF6ZOIESm9UpDUtlE5s3B08MrQn/ufV/FnEUgvKgyffT+mlQxmTp3wUwWhmEms2DBkyhNmz0ysR5BaXklPUcVzKgq8yQqBfIQXHZbr2XdiL2Ke2XHZWR7tjWPJ/j0gpV2RY/2ugCcXqPn0PjrPXYLg+O8jm5vOeQE+rIpCKWIuX0I6+tOHnZvFzfp8U01NvjXhKspOTuJaazJRKahMyrfIloMpu251VDRIJPSneoCd2/2f0RHLoM2gAz12Trpzu0axygma/OiBK+f1lDB/+MFMmLyTeWkiy2mxP9S6xEvX1LCpnofz85GenetwtswYypnv2imbNpvBL2OuOK5w2thvn7U6pzWGnK/sNthKbkXI9LdL9bpZfLzq9P2XXj0J4v1gQx1NURP5xx6Yt712Ww9R+7kpgif2o1DZy5Eiqqqo6b5gCJ6ltXOVuVrG6+DW4PHOy3K5iwvi3mDDh3c4bHiAImuO2YCR7FZQDAZq+e0ptBzL25OlpBkJCdK5nLYSIAPnQQW2lbxIMAylU5qimaQT0AEjhIJ7vvzurtXUda9YeRzBYjxAibbIUiChizo5Nqyke9zRthsqS0nTJ6B12xtQ83zDu51I0kyDknAO39PoPuh5FANG2duqLW/gXJxIK70xO0puJ8CTHszqlJLwuBYNmzgfszLtMrHZrcLExReGsnjw+YWjW829k1182PqLJjPLO0G3LprRlUmj8khsy7nf24qf5q5xNgDbaRYComW13FIqg1nPzWnpnKLGYH21g6ucfMkTaKmkn83eulncysl4NGnaKQpq92YMQEYfzPpRabsKEd+d6fFG31Pvm+UMoYGfye0cy2noikZxEh2jBQ9xFyLJwNvdxuPwPQ6RdqsOIC/SWRmKxAP31zxiCm7zocxDhOhvQWmh1SAzHkZz44WvcLS9ztbEC4LVtduDaWZblobebGbM9QShq34895WL6tixha30+vR+05wmTF8+loN0+35A5kd1JfrJ0QG8WgR7FMDZlJZkBaAnJaYvz6RUrTl7DeNTPzuUTaG9QGQvhlk3MPHcs3pgKaATaWgi0VJC3fZBrX3UrbaW/K6t/yBWBz9lsBtOPkjshA2nEGeTrtlVl9cXjvuTk3S9bEcAvuIzzGh5lyqbF3PjZb1n5+Uh8sXiyrG2kxQ6i6DJOzsaDGL1NHTt1CL69bR2B1gKkea0GNmwjFSWooJ/1jOaF8nhizaHq/Gmjsr6VDXk6qyK2yeqztYF6Lc42bz6t0r4nLr70fJ6tfpamWHbizdcEXXZ8DyCTbvKUd1+SmZ49q3T/Q/WpWbrf8ds8iiwTi8fRNCOltY2/cQ5bg5mdZgFPhGCwgQRZ7EeGSbuRoUSEhVLS7WcqjuQ/6B2Qg1JhZZ0HTXtxGn/hb/IEPJ2UoklFmbGRXizqsM3R/GuX9vWocCvH7dxam9bmO2+8QHOzcg4YCQ+aJhnUV03sfK0Sz6bs/XcptYkM73KzBmxZ4w4Km90EZo/Dnp8vf8/YTauZON8OXvr0AIfOVzYu0LbZte2k6AAOiQ5AW7sg7ZhWWaDaRDEedGIChi28lCMbD0m28X8ueDj8Lp6tBWxtUwpl1v04YPrhyXZx87VlZWpWrHuHHp8/jJawxzvzd7zGoysU8al6hyoHWrPNvr+83ii5eenlt53uKp/paPC2FzJ4fZ3dxuE8cSoReoYrZbq2NjsYEVy1kG7rlnFJ+BMX2dBCwCSCCC1kHt8OYAURtqKZTBA34vSfpPoxbsfHHNJvItNp5C9EKc8NEDXcY6u3N4whElYBc11X9rcpZhMRj+E5ZpSp5WeVBaiM2EprU3akJ2hM5BVeGaVIf8MaPofRDgWm/FoWeDM76ZyBkGfW3c/yvCLXeF7Wb0G2f07haf3o06cPtd3U8xDM8ZrXJt1MFY3tz6X/fJgxG+xxofg6zM53H122fA9gJM20QNMEwiLZaBoaknhi9+zE3kATEVpSlKdSA3pWv1/qNyy5bHiOQc8+/2HEyP+mKbU5HfFrfe0sLc8uDBDFl1FdPJ7ITuoCd7JYjmyg0ehc/WPM2Mfp0/ftNPJ1HxahaemE7F2B9X4uXpxg4HvqHT/AnM55E+njj5/3uzhJPAvjmJ84+jQhPqjDMm7dlk1NErIsWGWoLUx5+xmGrV7iGhf9mBvonVjJzi0Rtq1zq2o1NRXaCqXS4Er58+Q6XzxK07p8mtaH4VG3osun86fib+hO6een07RB/Y7Dt8fJiatAy5pSb/Ia6Y77O5XU5o/HGLp2aXJepjdX8Ovy/6e+OK7jWTyQ/CwQ1Cyw1VycZcz9pkpLnVxmH0RqtCds4lnAr67/EZ+9y4xFtjqXTCq1aaz81J3tDvCMmEWu3Jn8fiV3c/bCTYw3VnD/m9t44rUmSnPtcWwsqp4vr8fH3BIV5O2f25sJfS+npTWXRLtJ4DASHPrRPHJa1A00+7SzOPaBhwne+zDzcwawKNKXE48/nPGDatA0jcbGQlatHEpVS3fa2iP0ZREDYip50RRSV6ozgPS2URoqpaZA2f6XNzxC1GhTBFuvTA5+AkY7JeYtE8rCfunZ0M7Lq+51LasJKLVaUKS2ZlO99SOPuq/90ThV9VtpqXc/1/qSy5nZYyYTqiaobXUnqQ2ied3o338wgZ52cDwTKaCszCqr5+5zb6OCAYn0hIh/LjmGZ2IT8QW99CxRPkhr/PNFAoBfMXTZ8b0Ay58uHLZI3UManXEBDLP8qJGQ4CK1ySSpLZYqfWVirXD7sCUamjX3EjKN2KlJSd/hLye/Z1OG3Soa8cXddvDzmiX8niupJz0BTNkv85mRiTS/eUC2pG0D8C1+xFjepkBuS9p+meLDiGo+c7/2uVQ0bM9I9HPmvy9p+ID62FYq+9ZTH9RoDVi/g73dB/8Yx9KnUuIAiUTGirF6hmC9UmqzSLjqnD0kXP7pDwpGJJXKEg7lb5egTlszerSNYMCfDOyv19uZQAMDxtfZxwuFqeqnVLh1rz3v8ntSfscy0/daoVS/fR4tSRaUHfjOxxxzIodfdo1rmZHY/fGQ5ZLKMctsBQybTOUL2u/scH4BM1/8B+Pez0weHn+S4rc453IVOxqZcMpZeHzq/I3mDpKBpSJ6SXMM4OvRO0u7zIs1IaEgM+mhI6W2zlB49lkUXXoJlXf+rPPGHUATInmtZw2t5Jhhanzt81pVHFQfHx/Wi+eWfECwvT1Zpm5/QXg0is8ZiK+yq0ToPsYBacuFEH0hGWxNL8cDSCmbgNfNr4ft6z7tCpxKbW5yuCmygN5ptaYNpd34e62X7aa4wmpsn+sOCtPikk9won18zT0XzjQ3Xvh/6QItHgm+xmpVQcLsnmF48Fj2Kb7r73PrCvhMhbbcYHofrPKjhmnbOlMoE0KgaZaPLcLZP78XOUmdh/W+8mjpxwFF2Bl/8pmqb8auv3eP7nU0I8tGcvYAdwLQj48bzPdnDciyVQb4HTF8yz+YqtRmznFFBzGHTBC6wFu8fxTJYua9ENAERwwq76T1lwNrHHRk9yMZVZ4+9+4QFUOhZM8SjL3eXPy+XSNuHwgYcujhHHrRFQybMbPDdqNG/h+jRz2xfzqVAbpFatuN5/dAxZ6Q2hahGNxDdqHtseax5u7B8b4+yKTUhq3Utj8lADdv/i9StlJevhQhBPGYm7iUE6+isf8o2oryeZOJyeVClxy00x3sEkiEpXrlcH61dn+B2rp5aIZg3nN/4id8n3+KU+k5/C1y81RwcZnowz/E6TzMuUTxsgbl6NLQkqpwtpx8uoGO4+FzBjBH/IZXsUs/3MId/FR8n38NT2ezA7yDzTbOpjJjwUOchbkd138eL1/lfPkHZCyz0z+TM1wnTjwWZPPG7smJZj2KjFRoZve2eX0ZJ2ql7dvos3kNc/hJclmvN35A9d9W4onZE5Z4KPugxklqyzEyk98CrU34W90TVU/jDurrS2hoUJPkTKVekm0TMTym0zxIM4mEl3azvE80aiuiFbCTM3mQU954Krls44fFBDaupjJaTiCQPlkO0obRotFzS4L+KKfxLPk4x8tH0tpaxLXHlgzi+Xo1SIsLSWnjDspSiBReI8H977Zw9QK7vMq53Jf8PKDBPF8HQe5K7maFfy0fNwYp3LlS9S9mcGR0BDgIg8VNKsgzjefpx+ecKP8fF/B7tvt28MIIwbrC7GQNK44+LTYY3aPaNa+vZuMHZ4PpZOq/8HPyJtn3tj/aQI9lTUmSm4Xuq17CGmWvDG5gblsVV9LK3bRSLzSuG3E1mWAFjfVEAgxJW5u6166O3sJPuSbZ7pW1E5CRUuq3VvGYvgavI5Mz0K7u9edfbuK517ZSvPQ47vmoladete9Hzb+BZ9b8iZVNnwI6IW2nugYZ3gEWuTFoBqMCXp2NAXVv+mmnbLv7+bn993cx4NO3WV9Sygd5g0hIHdpV/yoKSmjztdEU/dqT2rrs+B4g+cazhNks260JLPqOdoCUH7Ucoc8ZPV3LtUJ1jyeEtJVWgVhKwuD74qDs+0YyavSTWeXYPamZU5Ak82bCrpDaAPQUMqFVcmmCfIVz5R9d6yzCc9DMss5UjmXGos7VXofEliZLWmWDs+xWJuTG0xUww9EWNq8aTIl0n3vBfJscbQXLfREVdJZSY+mHw7Iex1nm0roLJ6y1x23a0hFMjw4GbBK3BWcQYCovcvS8rRRud18fr9mmeLutpNKruS99jAp6GxXIRBS9xV3CWbN6koizrmUp/zRW4EGnWOay/Nlqdv6hH5++4mVxcBXrXv0eUXNMtKJRZepHutlEsQIrg84cexRuXUybnk54tkoIlTXu4PzX/0NhLHNAx7WFI7jkSQnW/OfVJo5+9QWGLvk8uSzuIJvk5aQnSwjD4OT//Jmbhx+bHNdZ+H9NT3E3l/P78H3oXmWznOO9AMJBujHoXdAbzaOz7tUp/N8n18FkuzTK1H6lxBykk5lDVKJHSY7fPK8gY8c+y7GH/4dTtKe5gL8znAUM9husPWQo0yafh9efeWq4td8ZZt+gX06Yda9O4emPLwXd8a4wEtTrkjvz05+B1Oz+qpJce84ABAcOoezqw/CWqLHhIaf25cQbRxEpMMeIQ09Jtj3042ZOea2R8LBhnPS///Lo23OS67QOgkRfY3TZ8j2CRVA3ncAWh0goux5L7H+Hz8XiL1zKn13L2sKHZGltO7y39nosuUzX4uyggKv4AxupcNndlwvLaE7JlHYdiwDXZaicE010rNTmJLX1rfiAnPIvVjKwj/ycS/klum7bpjVrbIf3oOj8DrcfvfJzxi7/jF4b1+NJKEXSO+aq95LX6Nj95VRqcxLthOYl6vFlTWvN3zI4bdnYFIW5unXL0ZBp46KW9iZaojtYulapcEajAd575UTq68uT9iCBpCe2QrsvFiMYGY/m6UbOBwF2tKh3Z2trDjt2VFGdKKZgzaFJCaCWhH1epRQl7byICRYsUH6SYMr4xjnfKtwyhm2tEZ4uUPGuXEfJNQ0DrbUZT8N2ZKwF3bDf987xljR0jv/oFb6DrbouEpJt7evt8/I7yms32I5sI2EGzqWG1uRLG7cAVGDvJ58dPLUqzh/yzmFAvSp1edYAFahaQJDHVgymqHAyfn8PDDMokquHOXro8cRFIunXkIBob6N4s1JhKS4rwdetG6HCAl4pPoT/lU1z2bdlS08hEjyZYVPG09JcwNyPD6duuZr3LzR8tFXZxMGwJhlRNiJ5T/m0Ha7zaQipeX4gmEOl+R7ymibOugv7xVXmfULGcZZMnLR1Ff8c3itZ1kY2+9gQ/y4AH3pilH62gZnz1PPZJr2sbrAz+HfGa7hj4h30ylN+L2+pj2nTppnHFYyfdgQnnXRSsr2UBsKbPq4f0P9O3nv3zLTlWyPp4+BlI9Vvfd6E7sy75TCCPnUukxeqZz2/MX2brxm67PhegIFASAPQmfyhSgiWCAQaspNEJmkkkuVHk8ol1l6F8tHHOpnX644qGzGvTgwPQkj8frcPU0hJ3Gu/NzxZxq7btEa8Cbd//n4u4w0x2eWbtxBdW+nyS6T6zX+UIcG6XK5Pkrk9xInjYRk9XQk7AIY51/GkhJDaUtXJcJPaLAT0OH7DIBNzSSaEq7QcgJ6IkymfXM9AovMbURh6cnpjBz7KH5787BzXHeRI/k4SuDXBpGplF41YPgC+gHv8Y5EGNE3jn7P+yVPHPYVXT+lb/5lwxYfQf1Zyv8mYTwfzlYmnnUNuSalrWbdBwzo8v0ywelNcpbgsQaM9eXxv2Ca1ldb1pP/STxj/4csdJmRatq52y06Gr96ctV0aCmpBgGxVNk4PZxCmqhqRvAcsouDpP76HMceciHbyX+G0RzPuOt8kh/kKdr8as9A0Sq++Oq1U3J7gjuMH88tThvPZbTMoz1VzWOuKejTBkPPPpfbvfyM0YkT2nRxAOO+88zjuuOO+7G58lXCg2nKnusGnHbSz1u0Gy2jfwcm5cM5JtCSpTeNlpne4j4ePv4i7+wXYapLa8hzCHFeK+9hhFBLDw1aKMRD8T8xIrhe6m+C0Y/V43JC016fPjXUJ3d/+Ib1f+gO0qfm2YegkzPerlsE/7sTounTSumUxcgPp422r/Kg1n9jdspsF5eXM7K3s1JQaFU/XO+Bl2qToXfeRFAYKefDwBykL70VCr6Wkl0rAsxK2dlOpbX/CGob4NMHvzxjJoYceyimnnNLxRl8CPjjjA+6YeEfnDbuApukMmXY4WpZEFQt5eSPIzU33GzkRKdj9ikK7CqEJhk6r4YQbR+6zY+wv7Amp7d+o8dl3OmokhKgGfoJ62z3WUdtvDBykNgC/7ndN4vYlp23rQwto+cSRNWxNWoRECEGs0XZmSmBNq/r+9Pjj+Z24hrUW2SxDHW+AispFDBj4kl2HzbU32LTsI9rMGuYGGlV1biWPIC38kSv4tvgFLQTRhEwqrFiXJZFBnjOGl0ZUsNM5qNkilMHclJtZBnUu9kPcjr9Dpa95wj3x6LE+XTntMn7FVF7AerQKZKYAq4JVLtGSpF+yeBzbPlfO7HXmdS40kzasMiqpaG5Sg50lC23Cgb+lkuIVhbQ0NCYzuq2shEwIYwedA1rmAIc/GiWckn0lou18Mu9w5s09EuiY1KbH40z4TAWSN6/ozSfzZtDamsenn05h8ULbIVO/uAj5zCns+Mx23mxfWICmlZITtX9Dvd0ObGsYVF/voe/6lRy9Yi4P1p/DKfyNftgBZ4AyuSFJXKtvD/J6kxoAxTFYnJ+uvFNoRBi2MwEtKx3HklwU+yMTNzuCHIb9G/toZ33C4KEfnYXHSHDJYw/zu//MpdIoQHM4+P3xGB8818h4XkfD4Dj+SZgWHtyu0f/oMwne821u7lHBw56itH7JuBV8E2zbWkNDQzGJN0KM/OguGnVbsU93ZCUIJIM/u59RH7iz0DzxOC0B9YwnzMzTdUgeN5VkigL5acdXnVC/tb+wkOrCKlpa1e/RS3xGkTlJeHfhxRx02h3JbJGYFsPvUIIMtargSmFUkt8Wpj3RRsCA8jb7BZjXZxlNMeX8EBJGRxRRMVOZ2Z4rNnPDyvs5CkeZXnNXxvZK/G32Oyu3qZEJn3xITrMjwFOdx7+G9uSnfarx6zphb/iboNTWZcf3AJZSm8UF05JWyioRKXd7QrmvsG5JZnUxI6ie5UTKM9VK5+WXQTkXEuYFmJ/FdxMMpKvvp5LmnCjZRVKbM9hcJLdwAsrZqWGklQg1kqQ29b7LRBLPbU0vQ5mKuPB2SmqrZG3ashujP0x+HrxipWvd0DVLuPu1n1G/pY4fM4efyGuS66JxR3Dd4w5qGIaODGWf7LhKuZm/0YxPHk4uCukadUYpyHTioSfFnLfVV9OkuwlqFh4otIkWhw+y+xgb04Pw+nbCS2wyXI1RzMhYD7o3+nlj02NsabSztxpW5fBUnyC/nekx+2B3YkPrci5qfBd/se2Av+iaOfQZmJt0bwVbt9Hua6L5VZvkf94v/sg5t9uTcG8nDiQLzoCJTxMUnWX79cq2buTaRx5wEf92BHLpXarI3UcdeQSHHnoos2bNIi9PEcmFeVyvN5eTx//TdazJ0VUcNub/MWvET7Dc3k9+fg6HLXiSC5e2I4St5Dyrx1FcMvQS1UcM9KrhycxMgKOHVSbHsULo/Oi4wfz61OH0K7fHTJFwb3Q9QL8jLqbaetY0Dx7zXeXx6Vz69E5uXf42AO+VvMdn+Z+xYcKP3deoZgzaqPPcNRdGnMmACnUsb8A9Twjlukn1w2uLmTHYLifb/eG/46urS373+HTKujtK70y0S6EetLid3htiFJ9+Kj2O3ESwKMaJW1VJ4W+oUluXLd8DWE5yTSqlNs2h1OZJxIjuZ6W21kVq7hc3y2W2B4ezreIumgvcjk5n/LfdVPhuKrPnAUuCPXiRGWwTJbzADFf50VfzOw6mxYSfbaIkbfnbnlRnvhsGGgOkIqFU5awgN7Cjw/ZONGMnY1UmNhBwKHF7WotobbXfB2c3/IXD5H+z7isYizJi2adoSLS2FiZsFEQSsKTho4xKbU44ldo+mzct+bnJI9ge9BF2lI0aJe2SGN4Mr57uLHd9tzLzvW1ucvXyZ2sQiQTSJK83NhYTXvg5gTVLsYSBJJLfr7b75ovFCPsr8eWciJAaLRZ5Ke7ngrZpRFLGcZ/ueD35eXDcLv3oSSTYttVWyMmX9m/mVLHWUtTch7SpuJcu1TmFV35OcN1yjNbtOHIkyHcEjwxDp7RxpyuhjhTS6Jo1tpPXSVK2rg2G0hDIbUknqJc7FG8FSi6jORpHmDbdH1L32Httg3hl/UkMG/YnrjtsEMcdq+7rwjPPQPPreKTusvHlfp1rI/C3IT0YkqPGIRbpykixOddddx2zTzmJUYerJJJweDAXn6JUCWKefOpO1vnbNjUGHlKo2ngrlP9lVtUHXDjRvu8DYTV+bul/PIHBipAXSppcQaERYXy8r3kZFanNIixM2LGJmoCPEbkhpm9ZzcGfLObEMWOSF6dtbZTcdnUNW/Hw8w8vT7ueA4uUje5d0BfDvB4XTerJUUNsAkB4dANNT8/JSITQNA/CLFk4oHtfEn0DnNPze7T2NUsbsQkNRfgb3a+YP58zmtPHutWarnrlBR7/1sWUF6cH+L5m6LLjewG2j11j0twlithlKrVlrBHmQPPOHWi6jkxI9MBYhF6J0IuRDqW2bGVCbagGrQT5aZ8ruZ3bKSxcT2Wl22/cEAgxD5tklTDnpb03rXG1qxctFGoxhKPvTWap0XiGBLH2xX2SfcD1CW6St2RM6nIS33QSGIkgt/HjtHaGZj23nYeQ9AzqDz4twQMbN+NvUeWo/C3vuUqXpe8jkTwDvd1up1ukrFab3O77/haoUn79wwaWE/TqpP5UMUfynVOBd4THh+8dN0HLownOGXgOvzj4cWRM+WNjhkDTPUw+60JAkdlAKV30LexLbW5t0ta4UJxa7jGd1LZk4mDeP9jNIbEU0AAu/sNDjDjyaHYbpn3KLSlh1KzjOflbNxEybZceVnYnFAjSbdAQjrr6W1z0+weZ88h/su5OM8nsxu6WS5v6Peh3FImtC/GWbyBvRl16m55T0SJhDpu/nEvv/SsA5T17M/G0c2DA0RDOHM847KbfcPTll1PUbzdVZPYRAibJM+z30C2ofkOfwx8odP0rQ2gD6NatG0OHDv2yu/FVwoFqy52sz3UdtLPW5ZpKcl8qnDNwp+Kp5dtNoPGkOJFdwVbUvDYXd5LEDlnAOeJRrhZ/5HHc5GivL5dArJ2r5yk/U1tLSgnHLCZMdyz3v3ImKz+bDogkMV6PdzweuWa6PU+zdtXQrny7mZLmrfKjZT2Uv61usB1HPGjsc4wf90aHx9M0Qb/Cfsw/ez51eXVqWQclny3Szv4U5MmImrEw4To49nfu5aZ/VHgzx9EPBFxQrWya1xw3jB8/nn79+n2ZXcoIv+7v8F7owr7B6bcdxIX3ZBZn2lMIIZgwuzfl3fM6b3yAY0/uzN+gDN4JQoiHhBBJ5rcQwiuE6C2EuA74EGVAFwN/2aPefk0gsbK/1XchVMaO5VTfl2ahbcE2tv99YfL788+9oPqAxGiI0fCrReT7VFZQe1k3VumKANcQUo5kS4nFCHrplzfatW8Ng3C4nqKidfi8bka7YejqvBxezig+PmSMq51AMhc1yN+ilSD9zcna6ZZSm5HBiEfxJ8lvDez6g/mJsJ0JbQRck92OcPJ7L3LMq//Iuj68ZB5Xvv8zznvyl1nbnMe9/E2eAMDwqHJq5plEnzWmMnBPFjNdPsvkRR9TX68GYaPlOwAcIv/H1LWnc07bZI5dfaFr38v7XMuabZuSJT/uFDdn7YdTVWZLJDdjGz2RSCe1pUigax1IV3qMBBMWxpjz/ItsXtOPlpZ8AHZsrya4ZViyXdM2nXmr5+F8Cnw5Z1DTXEXO8qPwtirDn7PJfe9tHqDOs+zZbhw+VynbOMudgF0isGVzPzRpFwxMSJ15hfP59WY/LUuPIbxkHme3TeaYqHmMuJtgMUm+zj0f29dMhm0H+jOtPXiz2UOOP5dXL7mNk1/8L31WK+JmYdMazmpTwX9fWyGL2uyBbFyGuGtjgO2GRt+Cvhzf5ziurC1jSLc8LnlmJ9c+YQcYPHGHgsuW4cybewSRdW3kNaxgW/BPnDzse8n1I6ZXMuLju5Pf8xrdZAsBbCrdzH/Gb8BZFeH2YwZy1+wOJq/m4LXy2zdy3lUXcN21t7HFP5o/bbWJoTdceDHjepcmneAJLcEOv00ALN1ik2vXLfgrz6y9j98ndpjXQxIYX0Bo1Agsn0ld7lIiecox0A9bGQhgw/rebFgzgDmr/kq3TQ1Ur1O/jzTjH764RHcMuP1mKd0Riz5LLqsK+Di4Ip+zq9Q99uSxT3LtyGuzX4OvB7rs+B7AyvhOZvWa91gcDx5vu0kW/3L6tnX1Spa8ayuEtLVlJmKt11VgSpoTlfrWQh5jNmuo26XjJNDZ6U/wCUN5SFzgWvfAyif4jbwAo3JN2nb/ErOz7jNVyQqgv0xPKIzQxDlSlVpqJ0A5GwBV1jlTPwFCplJbWwbSXjvZSW15puJYFF+npLbhfMgl8+9zLYvusG2rN8V2FjY3kBtrASQhWqkwzwNAM2DwPKVS5vW51a9WF43DI7NL17sUZsyx14iltj2rq1TjDkEmUpu6t72LdFY+fwkYHlq9mRXoFoRtp4kecIz9xlbjjxxPIHCsfT4Ihie645FqrLXDW0AzkiazHE7U58jATBlTLMjp7/oejEQo7NfTfgAlbB3VA2OHTSIoqKiiqDpdzn11eDXLcpalLY+Y933E4QDxCkFwgHmOHkHlbTbJIRbJ5S/9D+eno07j0YsP5qkrJxAMBhk/fjwjR45M2r+jr/k2R16h1MRKfR5mFOdye3gLv1z4Y4QRJxLpi8eTw58G1VHTKrlh5nHMD/+L2q0vs64wmFRqKw+V2qUAvrMOzn3W5djqU6oCXffNP5OxY54mL+hl1tAsmeujz4cblsGMO6DcJqT2GVNGcaPB7KnHwwX/48/n/JmfnvPT9MDT+c/BzLtt+dip34WygTxx+XgW/GBG8mc5+bgzOOmkkxApAZDq/gPp3/e7ye+dVukQgslnXYYnOCG5yBPw4c81S8X/4C7V7Mt2rn056LLlewJhfxC6QJhsMSkE+dEmYvuZ1Lbtz5+5vjcUX4Ph7TiruQn17K+jig8ZRQshfpNzJU+YtlbALs9xO8Lfw6d3uH5ww0Ku5Wd8W95GmGZX+U4nprS8xDXSnWjTik1a3rrFTZLv+frP8bbb9sVDnNPjD3GwfJ1MOKllFJpJPvNt3UBdm3qHb2/fwMa2jgdmftPGt7ZGiLXax2z0guErIOIgpE02Xkx+9ma4Tbwpc1FPQgUkvAm3Ine0wQdGglgswCfzDmXRwgmQiOFt2slhyzYCULN9G9uBYMOz6rziMcqDihDkjTfTr1gF9I24e3zjNct9CWnw9Nr7MBoXUybzGBBXtrGouYHgWttu5jpIaK3NjkCsdL+jc+PtGc8xuui/tETVfG740k956bGL2LpA+Vt8vgzjiJS4zvZtdllKZ8Jcoj2Hls19WP/W2RSv9uNrrU/bVW7UJgE8+P656hyiCSxhVxFIfwYGV+dxwVHD6b/wc3KPVIl6M2JDGRWtS7YZNet4Dj/nIqYVOcqKe62Ajnt/Qojk33nnncdZZ53FsNwQkwoiPHnwDI7tdSzjuyuVs1xT9aZgdh+Ki/9AyLOJ3HKT1FXUi5n1KwFozK3h5r7duVwLcdFSdd37bFrNoWMm46tSz37CiOMJHszQxU9Ru3UDAXNsIIRg4o4NBGNRpJQ8daWyoVE8bDIiJPy5PHDuWH55qp0g6UmOK9T114U3GbjyppTX03O8EMteds5Svj306MOpPXc0/zzzCQZVms+3kMljCK/OlH6laaQQ3aNT0NhA1V13ZT3G1wRddnwvIFkNRegg1S2mfNA6RgektqUfvEu0tZV1CxdgGBJNz8OfewpChEBKNKHu1FXF2e1oHJ2E8BCUzcl59TLRJ2PbhlCEB8Qlye8x8zkZvMaem1Tu2EJUxMnzGhnnnm0ivURWYdzun1QXI4mBfJqR1KY5aAM6CeL1w0iI7OeZjdR23P/sKhlaBnsoBAxpj+KJraNk9Zl4YulJYK725v8e8kQGPGXbDkuQxttuxzSc743K/CCf3344Itc9/3Oq/NQW2Ync1QX22EPmFvNG4cGqFL0QlEdstbSElFz79ycYedQx5kEtUtvulUa2yo8aDlJbjkenIOXdqjmS2iMFhZkJc52gsFndNz1HH8whZ5zHoCEDCNRUA1AwezYTFq3hlDnKd9xv3CRyCpUftG7YSCr6pAfXLSJDztGz6PPuO6511b//HSXXZvGdevxQrPwOnkgDwpv5Hqr7xz+o+u538YeyKwmnwheO0HvSEbvcfl+hIk+NvTyOZLN7B9Zx38A6qgLZkzm78LXDgWrLnaUEOipb4FyXXn5gP8OZOOIUNmjGVD/rpNqWE0+jiMGp85bFHjvJ9m3cyVsJTUM3DGob1Lu0PVWN08SARR+7vjtjT1pLXjJ+aSmgpiq1WXPLytsOZsmPjmB8L5vE22r64Cb3yC5UYqmEltTkcOlvJ1M32G4bDvciEOhYjXJ3E/EtUvc+JS/sCjQNpt8CuW5/Z8kVV1Bw1pnkHX/8l9SxznF7ryrWHjL0C9n2Lnz94fHp+DKUGu6CG1+Y1GbW254FbAXOAOYB1qi/DVgI3AmUAOuBY6WUsQy7+ubBlAJ3KYVIYZfX7EQafV/BaFI/T55XGcBYvh2olJa8tjkR1rQE+aPTA4IWQsXuSZA0dGLhrWh++5zb8fOiODxtWyvb/EehW9kRNpIKMq2+AAZg6OmW8zbxY1pRE3unU7wjODORAVbRPa182p/lqRm3LWhtQo9mn8Bq8Rg5Cyejbcz8W/5QuqXfCwzlJA2ZDvjtWGUTo5zLfdSu8xJbpAYi/dfu4EF5sipX2ZSHJ2Ug99IWpa7REu6dRuwCiEh3ZoLmuA/PXRGjV2OCsbG5rjbh5haKt9pqOwVbBhIRbhnqbEptZVtaKNFV2aryYnd/jq/oz/BJdqDaE+iNJzQNT+jQ5LLctig5LTvY3u4nvEURrUTCPTGcNHgruQNyiG+2A/Ze3K+bXDMTeMP757AmfyHNBjxf7+FuMzN5WbtOUPREi8fY2NaQdNgMecbtgJeNtoNk2/KniITsAVS7FgEEIW+IC648kfmHDiCxTZWKKQtvIvHuvcRXVZK7cyAL2+zrddiUT9gm1cDc5yjlFczxUdJgEHFkJw6P26o3/rYShn2wltpVqwD4fv02ii+yAzwHndCX/Hr1nH7nbJ0fnpz+yp/V7zi25UV54cQXkstOG1vLiSOrzQKKMHn7e7y80y7DqmkqW9pfWoqmaQSDQUTRcayLaZCvfjtdVxN7ywkeF3FafOoZzWtpIr/Bvg9zF7/OlLkL+LuuM78lwXP1cYpnDUL0PhTNLAmg9RgPs34BwGDc2a7FxRH6oM5z4KIm+i5TzvVfHjYA77pmZr3X7FINkEVF1EzexqFjPkguu29gnXufwWKCnnRn4dcJXXZ8z2BlNlv3ls90CrfjT6pqfVn8ir/ccAX/vtuRZZ1F7fNPvktc35+tP4HHxSncIW7ZpeMk8BDXYJtDDfQceS+3yJvw1/6VAnbQW1vQwR7S4SR1WZjIKxnbDjXV+tsIJBXedpJJrt1ST21M9nv5cneWbEdqoz5TXSWGF7+DCF4nl3H76t+794Ok5/ZPXMs2rLLHRFrKTaFJCQ71XicZzR+OMTagjrd1S51ru7nrWzOqVo5eoVRKdRL8UF7PMe++lFyXf8h0TnrhKaa/+wYza+zAsZ7iWNHj6t5emJdPfIty9ET1KP9X+AKZENk4j6Efz0U4SnDN6K1sgeatSWv/tKjho3FXU1BZzT/GFdE4sQfeyHGsK7bV4LKV4nEiVFDAjhz1rF1/vodYT5U9md/oCHYH8ohobsJig6+BBQULeGexfQ9Memsbowf8gjPOOIOTzz47udzKniu9fBgV3xqDlmM72leefCFH/vQm7rl4CoVhH4Oq3EkVU6Yo+f4eQ4bRf6L6LITgL4N7cGF1CSdveg5q7OSOYXlh3j9yOCO7FRMXCX5Z+Tf0PB9DVkap1HTOqHSot/oj4FHjhZuO7MeTl49PEtze2TCacDhVGSADwsVw8GUuhZVuA4q4/A9TKepeBtWjKAuX0SO/R/Z3mRUkNElpPo9GyOdJOscqyisZMECpD/y6fzd+0qeai//wEHVDR+Dx7F4C8MDJh+IJqOt1+m0H2U6gMRcTzs+nT+/ejH/ji5U7/Cqjy5bvGSzFM02AJkTSphuaIL+9ifb4vp+X/3fLTjZufZMtW55PW6cZmVWD4w4fqEVq+5b4FXeL72QsB55J1WVv4scf7eDg+QsJ0cJglA30ZyGLX9LwOqN517VsMi9SsVMlvIxf9HnaNoXbWhkmPwRUEH7Z0rFp89y7Pmpl9LY4xUaIPHOeIb2+JMEAQIt3HACx9qlrBsGYvf9f9g2wsDBM/xb7vbXhUzsByGtI11wD0uei3rYWMBKENqaT/S1Fz/r6chIJLwnzHXrIqq188FwjJY1Npry72qcvFmNw4TrGvf1d/NEGNF31S2t3x6AmvvcCE95/mf5LP6Extp3EIWrePbDRy4xP32HS4rkU1NtzMr1dHXfIinbqV6S/+J9ds45e0SizGnea18t9jrJlG1Me+jazywt44KyTeL5kONsXnseO1SPYvKknFXnukmqe15Qd8/6ngtw/utVnW4QjyUHqrH7lBlq3jEZq6eMKgEDcMEsPwtJ6VTpzXM9iirx34NfmIczycX8+ZzT/viK76mCfM/OZKn5lfhMZlQgCWaoWONGtWzdCoRB+TeMfw3oxIi+MrumcPUwpj1ZVKkUIze8hEF6pNipSgX+GnsJlffpxWYHkzN79yfN6uEYLU9kmueTVJ+izeS05w8opOL43AIXdurGmoIQrtv+LIz57F4+j5I5I+hila5zyTLQ/3kEzmNK3lKn97Wv63s2q6oHHq9oGAhVJAkZq8EXz+63LlBEWqc0KgOUH8tH8Vt/sUoQiS6AwZ4YqA6XnffWzyTtClx3fO3DreUlzjiUQIkBLy1KamzP7r7etUb60hi2bklUGFARVwWqKPRpeIXivR3Yl86jpw3aqU1pIVURPRdwKdDuMyFEL3sDvbyLgjXWaUGWhVC9JJndItLREj0ykNuEgta0TNbxf1DEBR5eZz6Vo507HPm2c9qO7Oeqq9LKnqo8K42ZnJ8zn6X0IRhOc9+9/cNKLzybVtC8bdmWH/RTBVH+AYFhNPv+bcwgH97TnU+N7FXPnicqWS2+Qj/OGJYm9YZ9D3S0l2Sqcr/avZyi9XJbbUdko+33shC+FVGC9a0fOdPvcdwe5bVGOmLeM7iPshPCa++6l8ud3ER43jrFz51EwJF1p/4Tv3MZpt9/F8MNnMevabyeX+0MqzuINR9LeyTlTplB88UX0+t+L9Hrt1bR9Ou1QNvh79KDwtNN27yQPEPzrsvE8dJ5bsKHA62FWaf6X06EufCn4JthyIcRFQogPhBAfbHEIFewLOGfgmkM92lL3TuwGqW2DUH7CVDv4VMGRyc+pic9xTUM3Ekm/ZIsn5T1tWrGR8992LU+tenFQvDcnt41DmsmpmiNhbv74gZz0gfLXan4PXt1tY7eZx8hzdPu2owfyk+NtZWvn2FzTvzDNY5fRZlY8CkR2nYC8P6Hn5lJ+001ovgOXUCyEcCQRdaELXfgi2KO3nZRyLjAU+DPQjhqhO/9iwIPAKCll5tpX30SYMujuSaawpb+lhCUvZtx0zw7rnkBIpH1MRyJXUo3B4QC21NEayWUVtYTD9bT1dAeOnCS9zWE7MDmX4fy29ly6jXmbh4+7lCahCFwPcX5aHwUS6VBr6D7kXVfQdl1BCQUltlruWfL+5OelqEw4i9zWEQ6R/6OUja5lPxc3scBVaj5d7csJGeuYrSD09MC6hWLcEue6qVpilbrYLkwpUvP4IlZMbksTl7z6BN0+rsVLHA1JNMOkcHvczDCvH4I3QzBBlUdV+JV0K7wNqjd45K0Wyjb3dS2vXreWmtW2A96TKEJPBCnYMhrPTkV2y1TODWDse814pI63wEdur4GudVUzj8LjtUmI3ogfj38oHr89QCvc/jmaEePjlgTtUXU+esztsBcCvHI98U2b2b44ROFvvUSXu9UBSk3CQzAcoc3bDAiebvCxodkmqU08/Rx0/yg+bA3y1+YW2lf8Gb3BHmgULJtG9J2rAVjRniAW38LQQTYBL+gJEPQE0YSGR9fYdPRQ3s9bwrvTFuMpixHfMJcN3iAixfMrNEHAJIH5ddsJEspJH4QddNJIPMVBmoIeBIK8hjaCtep+0fx+cKihOAe3D8XWMqnATWh846huzDj7+8w/ez7lYfs66FYJG/N7uUfSY5aDIGM6s3RHrfDZfWfzx+l/5NDhv2Ta1GVomjqP0lI1h0uIBDnb7+eqmhL+tmU5Pkcp0p4zN9H7ZA+XTu7J8qhhUzo0jeIeyjngCWV3ZvfsNZLT+DeMu8q1PM/vQf90Jxvq/AyZZEtFNwpB5JJfkDjj38llZf59G+w7UNFlx784kuVHzel2wHwfR/Hh9URViwNFNSjF4eqV6bbtOY6gSds9kslbTOAPhxxLk6NsWDVr6IN9q/TzfOqy1R3hbHk/FRkU8Q9dHaLYDKA6YZXPjgtvkgx3MBlILea78KyW/3Cs8U9G8h7r1rrtUUdqo7WmzYmlKLVpSPIS6cmO/Q+ZzMiVdga5uwyL+zhCGmheCVKyYUNvYq32byUr+lP9vUvIpYHIDvd2rTEPL8TdippFay/l4IVvcsmrTyCA7qzgkv/3EPnt6h7VdC+XPv43flkSomxwGVt65COReBJu545sKmDQoF9z+okvJseCUU87D5T9K+P1yd2yiH6LFiEcWebDy4bTa2QpE0/uw/X/XMu9Tyr1oc9aojSg0ewJ8dL1k/ne0QMZdWQvZn5vBtvC9m8fmHZI8vM7+W51VgtOEjhA+8j+FF16Ce8eNIBFE8zxnKZz1bdv48Ybb0y2i4s4UT1KvqOElve7O9HKB9OrVy+Kym2yuhVn9dXkoOf6EI5nKR4IMalPCVP7ZVZRGjFiBLfeeiveDAEPKofBVR/D2EvSVjlt9/gTezNtSjc+mDCQbsHMQZKLJvVkaE1+xnV7E/9ZNoP3txzlXmgRIrUUEo01vXA4a2aXF3JOVTGRgkK+CHSPPb7JLzPHjrfWw5E/Q9M0Tj3tNJcK7DcJXbZ8T2DZcoHQBML0M0shyGtvYv3OzCqVewtv7Wji/E9XcsUn7/Pd+a+7XO2tC7ejZ7Axo2bk8H6R/cw1pSTTP8IZru+JuIfYPia1Vbd5ECmlPcfwDkfIf1Mm3WT1QAbSnT8e45h5yn71W5P+HDe07OBq7uSX8mJkwoPuibpI4MeujTJ5S5wbXniFhTvfpd9iRV7QWm3VHIGges07aft2Ijn3j4co25BOfDJampj+5suM/Gw+stU+j89WPcLgtbaS9IAdG9NIbb5YjJxFH1OwJUOZdcc4ofeixcnyXqlEeGHeIcH2NjV/bFdJermmKk1hs5oTvjTpc5pe+C7Hvr+Ac/7zj6SPod1Q91NY+um+bSNeI8HwZUoxxzAE0Vb1bu2xMYYATjv3Io784Jnk8aviCf61biN1MfVcpCoeAPhjMX7dv5YKv48XvjUZIx5g7Yen094eRoTsa3bIwXPpFZ/CtM9WUvLMNvyf2WOIaMO7PF/7cvp1AjRPJYYn3c+yOB7n/HdeYdbcN9hqqHHpj48fRFD/gBLfzQizdNqUfqUMqc7PuG8AT0kBYWGTXzKN5f2mPbr4kB5Z95N1/54cpk1dRnW14zm1xjMVQ+Hy92Hi9YTGX8b3hw0nnBxbufvh9XqRJulW82kMOOEQSiffA0B1dXWy3YwZMyguLk7Oye87axR9ytT1KQip4wqH368wrJYVF01l4IB76N79quQ10FJUV4U/O8kH4JhjjqGiooJIxJ4naJZiXrAYQup3FJ7MbumSq6+i95tv4Ckqyrj+64QuO77nkAilPCZ0NL9f8YABTVOB13ffOyrjdpFCRzK3qySyoEdE+ZhzO4mctJiJ1VYirRMPc26H28bN5DNnyeUh/V5izNh/Udr/OVdlDSfK5XpmSjU3G73ic4LY8yIpRZrKsjOYb6mda+wecT9uxHi05ddpy3OaM4v/VPTqQ7/xh2RcZ73TCioq+VPNWTwyLRPhO47mkZz5zL844p238ZhzpEQnPpZUhWhQ7oCeJem+jhN7lXJmZRHT2szSnObcxSrVCZBI8RNMO+8Spp57MdUDBruWv3rDZJ67JnvJKFGuqnwMm+G+F70Z1FrmPPoUk89Mj5nsDlL36i0tJe+ozM9BKqaeezF9DrIVsnuPHcf4k85g4qlnZ93GW1WFt7Q0fYV1fh34W77KKM8LMKlPyZfdjS4cADhAbXmj43NHKiDOdY2ZGkgp75VSjpJSjiop2bf3vFOpzVlaqN20dZkSfDvDWyL7+zmV1BYzldqC8QRCSt6uzqx4JlKSo506LKqEuUYOQWati9EnoTFgwUcA/K3qJEp8Xr53/Ry+/e1vkwnfOVHZmESjPd86e1wdp4zplv0k9zF2bFA+24KKqk5a7j10KZp1oQtdSMUeU3illBullOcDBcAE4CTgVGAKUCilPE9KudGUWr1iT4/3tYBU00snCUhNOq2XtICt+2BskzJfTWAkfWMCybKmtXzoWcb6Ai9S00AI2j1edgbDSWfwj8Vt3CTuJhOs83mb8fxx8MnJjLSHOZe1opb7uZR1eXYW6AIxOG0fiRQndwN5rHaUQSssWkNp5Yrk956OMoSvClUSKiZ8GImOZRoNNEpMYllY2mO1N5jsavfRR0eSDSKeveyXQgc1yFN+DN3wmv/dy5f+s5aSW70UI9GbFSFp7Du/tfuQIS1WmEGLeFs+jctHpa3vYSpa6YkYRWyntV4NzHwOclcoJYtdTyQyJuB6EkF0r3L0+MzSLuUJQf+V7yfbJKxymbrA43H/Lt6AjsdnB2nbtnVP7++Kf6MZMQygzVBOIj2eTlz0BNS12/RRPoHPBC87OIt91kU5mb+RiAXMrqjz+9aoG7n/LPsa+UNhlncLIIRObmkOld9RJKk/3HEzLz11FiMuvJeKg5TizpqoJNS3P+UDhvBU71reHtufgB4g4rUdJXU9hvOTk3RK+/ehbM51VP/ut3ySp67TmKO7c/BBrzF61BPq2B51HZxBej2DNHtkzGjKrx/FKrPciICkOo7Q0rMviy44n8offY9cQ3LxTjep7eQ7/s+lrJMKaw6h9T0Cn0PpSZgTCqdsviY0xlWNSxtszp49m7PPPpsHZz3IPeOu5qZeVdS1Kcec0VZPZEQQXySBvzjAtw5Pl7nvNfY4/HkXKfJjBiWlIYN/T4/u16nA9mG3u9aN71XMjIFlzDltCJO7287KdkPCsNMo6z4s67l/k9Blx78YLAtuJVX7sUhtSqlN0nE26v6EdDyX+XI7l/LLtDYPiQtYlNNzt/b7OKqE0mZsUo8nQ7kxfRcd5r1ZiN8RIC2NbSYkm2msD3PiR69Q2raFgLSd5iFTIT9X1hOihZvfeJZBS9JJcRYitHP56wP5bJ4aLwyKu8tc+U1VlhypbM1U+ZzazrRjSqnNJoufsDSXmEh/7xbU1jJ6lU1qs0qO9tq8NqNSW/3Qs2iLl7N0yUG0/8oeG+V3q4Z+M7mOP3GBeNS1XdzwsE66g7qa0UTepoWEl9hKcaWHHYanWamdWO97GYshdI2BZ/XHu2NLWvnREQPLKSs9krAvl7qVqtRZu8dNktcC9jghWWYmRRFwxoWDGDKlmotum8bYiWb2sml/ncEBoQkqqt0By9If3Zr8/H5B+lgGwKt5XSV+w4EcSq++mrzSEvIcJUR9Ph/BoD1uiOrqdy4Od+6ISbVpQoikY370gMxqMbuMwh4ulbRMCIS9jD26xy5nXb5w7ST+ddm4PetXBvQpy+HjnbM5ZFSKiuO4q6DXoTDcTaKxxqdaFvWVLwLN0/G+vunOri5b/gVhKbVZkm1mvV+paeS1N7Fia/bSensD9eZ88g0xmSfFCbxfbNvLbQ9+Rn72/CrKWlXb53CXXrLmxBbmt4+gPUPZ7b0Jn2HFamx4iHMGf3EF+ftmIZ4ahm1Tije7/SDPrn2A1vZ2fMQoZitLl46hsaEkSajyxSTf/UzZqNzFD7B5xVNUbdxE9+LB2PEAAMK6SURBVHdfxdPaxOac7cl9PT+oY8UbL1FkNMia16/OOM8OxAUHrx3KT7YspnCZXSp2Z/NKhq9ayCWvPsFP/3I1Zyz+OC05zvKVWD6fntJWnrYCItWr1zDi449ZXK3mbNtNvmJ44gCqI9Xk+gvNc46BgJ7PPkP3xx9D11Ucan3rIi6LzeesIy8i76jJFJ52msvntGaJKucekfb9EGlpoXnBGbz37glJX4RuSGaPrKZXTQXFhkosCkv7t7N8Q15itC7IbKMB8kM+jrp8CHWDVODLkAbe5er8dV+Imt/8hoDpC3ASOsaffwPNKy/F1xTn531ruPwPU5n9nVH4gh6OuGQwB0l7vl3Sqib9n8XjHDPhCK45bAr/vHwST105Ab9Hh95K7QttF4mdJX3wnPRQ8quRQTlWCMHKnxzFd47on7buC8H0A+DxQ0mfzGODVCVArxfNLE3i75HHeRO6M2bcZC666CKmTbPfAbW1tVxxxRX4TMWCQweUcdU0pfA2qs5NMg+FbJVXIQTl5Uejab7kNUgntaWT4pzo2bMnF198sSsRTs9X52oYIYR53tlIbULTvhGENgtddnzPYAjrPavhyctHmMnkYJULziyI4zPnCL5gyK3UJjQMac5rOxljNqISt8Okq6t+zMiO+50kMdvvmsLC9QDo/mYCWUhtvVnEKTzMz15fyPnL26kwHPPChJHWZS2ZiNdKHctdy1IRiKu5oSeFhBSLNbG2NZ3rUJCF1LaruHn2WNr8BnmbfsQPe1dxyR//ypRzLiY/159890mh7TqpLcM7KeLP7PfUheDOvjXMGd+DIdV5HDtczQ+DDlJbqlKbPxRm+OGz0uYetUVh8kPZ1WFevPlo5jz6FHVDhqf0d+/PYQrOOtOV8Lyn0DSdg044JanYtluwfo8DxDfWhS7sSxyAtny943NHDjBrXYOpOvelwvmel474akKo8Xxq+dEFuJOWdxdtwv1um1dagMdIEJYe8mKSRl/meUSqf9fj+mp/KYpKftIWZL1QsdcWXRHug8EggUDmeXpOj3wAAv2+WFJoR5h8el/Ke+y+EvKII46moKKK3mOzq153oQtd6MK+xl4r0CqlbAfeSl0uhNCB84GbUQbyN3vrmF9ZSMXVditbiWT5k4QQdrbm3kTKRMwwqXVOfOxZCTk+vMVKpeKxEZNpCIbJN7OAO4JAEsPDb8R14INvyV/yM66mlE1soCojiS0VqVnkP+O7GA7ltprKz4k6MtAylVcB8LVUEc1Jz/Sy4CS1lbCFZjPDvUW45VObm4oIxxI0O0pMzJz3hnm+8H15E37auVn8nILWeqx4gebrj9By0447ekkbhds+IzTWPenXpCk5n+KtbN0WwLtZIHQ/wXXLkR4P4cZtWNSkYEiHhHsbadhOBl9bOvmrGOWQTuheNm7oyY6VEzlcdsfbVsTHDfMYnjuUgBnA79ewmoW53ei2Kb0cnAUh1O/hMYlmAZ9OReMalstBlMabaTMlD6SWgdTm00lE7WUNq8eS72tmZ9T+HTRplxJppwkfIBJ+HnrnQ7YM+yum0j+6z+2Q+fl1TzP63cXktLRy8hutbNZvZzOCcJ5g7llz3Sdhc/DYEVLn2rMsBy2sftC+q5fTc7Cp9FYZ4cmdyiFWfvlFAIyqVg6k6pxqdrbvTO5rZo+ZDCgaQM98RRTJmTqVLc//l9/ktvL5kRaBT80bLKW2VOWZCSf1Ji/Qzu3tak6hWYNd82evvOsu5K0qmCwyZMuXXq9KnDD/Utfy3Nxccn3p96gTVvlRge1o6e714o3lEvc1Zh14OxEIBOjeXZ3rkBIlb19wxhkYra2ExxYSPmg4/PccGKv6N+mUPvjD9j3h9XkRWkT1pDQ9cFBScph7wfVLkqSJgFfnj2eqQEt34InhvTj246VE9oMk81cRXXZ892CkTF795ner/GgMmYmHuV/x5q1/onZqEZ482xmulEMyO07btd0be1gOfGf5KQ/pAYNYq7/jnEATpaZdHiXfpWzHdkZsm0/PXh+ybvP14F3Hce++ia7FlGvIPIvLY/fQy6PKPB/dOor6RDNbeC/LEQT5bVXUoxwJB8X7JNdoUnLqey/Qo/+7hAu2E5VeBJK35UROXQWvlHnp1r5GqaqZaGl8nrk17uB73prJ1B1yGo/VjaVg/TuM3zKLQDzG7A9eoqC50UUwtI4bKa4hEY1TuqkMT6u9v8rexaDpcMNyWPoibLvJvqZG+vjn79XH8Fb8XbR4lE8f6o3mkYw99xhY/Lg6e1OlRJokCl/Aw2U3fY92XefBT9dz6La3OHTbW5x8oR3M7bb2f3Rb+z/+3xAdELwbmc/0kUdQ8e03GPv9/wKgm/e5U6nNidziIJGjurOxKcaKtzeyIWAQS7gfDssGWgj6O5ez14RGQ0JQ4ZXEpCK57QoqelSwZvMahP7FSkxX3f1ztt53HxXDBnyh7fclepfldN7oCyDo03n1hinpK3LK4Ix/pi+3iEJ7k9S2CxL9gSFDyD/++L12zK8iumz57sGwCJhm4E+YE3JDgF/G2Fi/a2W/vigaHCW7APz6DsB2MNe15LIli4hq2L8C6MlHYgxGlpJgABsiZWwgs6KkhZ/Ia/i2+MWudToDfBnilPX1peTlbU4GzWfNe4PB29shAw9ISvv5Lt60gO2OdfWxLfhaHMHleICmpgDvNU+CCES99rZFWgsjVqk529A1W6gPNvB+XQ1jBcSMKK2ejpPSfESprJ3JogY1Tgg3vE5z7sTk+mA0CvgoPmsOBXdcllx+8q0/4S//fJxYwuC4ukWs3rKed6nNfBABT117HlvvVoTJSQtXs6yHh4Xldtb9W4N3MPSMUwh9OBCWwuThR3H40LP53pJ1/GndNnyxKPnHHouvrg6AsiYPK1f+hvoNXo6dpHwuFT+4DQDt+f8m97tuyQL6V44kQoBViSKO0RXpfUJhX8adMJlFm5pZvaOZIy4azEyzbFZ03WYmrbqOXkfZ/oDiqPINDZyXj76qPyfX/glf1XC2zUs/3brBxQRLE8z9/QskEgmKfu/ByAPxmkk0aVeERCepbXjVwRitrVR9Ws/psxSpqbQ2lwvunogQgt8PLeb67Z9TojVx6rLubGlshbhBuFcVAypT5rezH4T6tWnE+47g73Moues+YviST5DD9hJxrSPo5vglCznMid4FtSzZsQqfz4e3METp1SPwltmD7MrKyg62Vpg5pJIR3QqozLfHQQcf9BI+X+agmZWkk7386K7ber1AjfdkWxys7ffiWOHrgC47/sVgmxEdoWloKBKxYXT83rfu7xNu+gGtTW4ffUIqcldrJ1XO6k27HSadCN9OZqXlVOgZEsOArEptuYlG1qwbxNDWCKWyiiba7BhDNIblMDxO/h9gE9gMqaGbPtpspLZZ6xP8XzedXCnZbo6TLmibxg42sUJO5VvPPs7ammo45FgAclrt/UggPKYcLdLxvMx5pU8fW8tPFoKvfSEXVCsS9IgjZsH796OZA4xNJTXJV0U8w5jDhZRXynWH9uGUMR0nI1UXhPj3FbYyWchZfjSx75064/IjnFqx94gL5TfdRPlNN3XecH/AshFftnOsC13YjziAbPmnjs+DgM+ztLNKVy3Yt93ZNRhRO74lM4iGpJb2/pH4wV7vQ2E8QO9EBTt99rHGrljCu917k1R7T3mvndjnWp5YpJST2xMp9lsXvF0wlo/zhtGmdx5P8xQGqPrReMjgB3vs0nHMX7tz907IgYETqxg4MTvHsVd+Lw6tPTRteUltd877xR+/8HG/CPr27cuzzz7L8OHDO2/chS504RuBLxTZF0KEhBBDhRAjhBDp2v+qjRBCnAMsBn4P1JAtivpNg5SmNLpbpcLK2jUQtmNrrx7WPfNLJCkr2FIzdo8AaAiqoKLcBQebQHI3tmTqRlHJn7iEfDonxFlwEtYAF6EN4HUmc5e42V6f5RYObBrDaymqa679oicVXiKZVXUJxdX6B19dTU9HGbHcthaEmU3el0XUsZIZn37IsZ+9lGzjCx+BEOmej9KdCS74zzNpD4KQndWCl6pEWSzKt86y23brrR6/lipHSQdf7+Tn1lXpWYHW7xFpbmDJ4nG0RPMJNNaixyLovUcAEDNLlU3b+QYf/exoIq3qWpxSGmb68y/Qc9kTzt4DEMxR96wQ8OnW/tzbfjUPvb+ZqDV/1UgjtXn8Ou0tumtf0689hLJadzDbcs5EV08AKQhvG8DgWIBT3/uYya9vNc87JUBuBu+LdqqwiEz4GTa1F7OuGJZ2TZyYPfhEtT9dQwvb/fCGlEPL+Rz5c9yD0GtHXst9h91n91uIJKHNwmOXjuPyw/uQCqvsqC+FVDJ0ag21B2dXT1LvDkuprQPvzoTrYOBxXHXVVcyZM4err746rclMRyk2cCi1mU6IN8b24+nRfZg0YQpnnHIOxcXF2Y/XAfRImNJrryE8bpwibMz6JZQqlbbBk6vpM9pWDfT6TVWfmKFUbco6IcdGSiGcOaN7bF6YG+rKuavvHqrrfA2wv+y4EKJICHGuEOJhIcQCIUSzEKJdCLFWCPGEEOK4DrY9Rwghd+Fv+u70aa/BfC6sx86DRDMSRPEr1UTx5ZYf3ZFXRI7Rl0XxOTj54jqJNFtrYWtg99QQ4maW3HpHwl8mpTYjkdmZXyLtElw1bWuSgYBr+RkTGt5ly/reLHrtXNq29SRnZx8EYBju8dEo4/1keWnN8EIG5bQkpFKQGhPrxaHRIa5VmjQIxGNE2lspZwPdWE0Na/jDsr8wckeCe575gMN2vuLa5tXKd2jU3MGLvj1+oBRTBHji66jeqYjkF//5T2hIdGlQ2GCr1mjSoHtdLSW5foTUab3yem758Fku+evPCOWaxIZwEQw9mU1e298Vz0BqG+wvJm4SG+KtHhKtQcJjxqAX5gMgzLGldDiICsorKC8p5eXRffnDgts4a8N/8Duzuk11jeP7zgbg1prfk3dEd/T8fLaG1H4PKj042VYv8BPom/5K0QIeKs8ewGE3DOdDf4JD+rrLFaQGSp2luLMhbsR5aJufv2/zsTXe+Tj1iiuu4Prrr6fGVA0W3lIqyo9nzJj/prW9qUcFdcHMz0nuEUfQ4/HHv1HqIbsL6+fsTHlg5IhH6d/vJ7u4z87NT/d/PErBKSfv0v6+DtgftvxrbccBISyHdFIKxFqBLhNp6hx7E21t6/l0/p2uZc2ena7vwQ6UwfOEPcfOZtedCHWQdF/DGmave5JwtANpuBTo0u6bN0Oc0utVhEBn0FxiEJcdEwU97el2PNaabvPK67clP8c3fUrrhw9QMWYnj045CwB/PEFpYwsPyDgfbH2OtS2LiBs28T6nOf16+IhSWjIj+T204z6CDXb5zaLGjQz4/EEqeuYTjORw8r//xF96l1HdfxDV3RSJzYNBVdX2tNKcAavEXF4eI99/Fy9xSECkPUZei3lNHML9J/U7ibJQafK7JjRi5u1Yc/NN+Hvbc/5IpA/rnjuM+uU5zBzqDlBUb29IEsYSjt/sjVgPxjraFVdUEjTLZccc49fq3/yG4pOOI3jZ43DmEwAUxhs49L3fcvCiNjzdDqL68IspOVupyUemphOgLaUuTdOouP67BD12H3MOPdR16mCXxTx/glvF3bIDuhD0KRpAQcEYpcANiJgkkEHlHF9IqZ/tBoQQfDCqN7MiXoYOHdr5BnsKa8yTyKwkBSqwBTBr7GGcf/75yZKevoqwq9T3rsJJaAMIhWrxeDIT4/v27Qso5TUnRKby6p1AM0vQ5s6oTf7o2ZTavgn4KszJHfvIEULcKoSYL4RoEkLUCyHeF0LMEVam65cIpdGmyo8KIUylNjCyKLQltzPfIb5gMKnUdshpfQGBYZLaGrwdX+7oBlXSscBFyTbXdURqc7xre9R+xPflTcxa8IqrSYDMNrN+RTdWrRyeVBUVQPV2lSBWFV2TtL21piqblXjWe8NaPvpYKbw67fO18qfJz1b5tFDAfd6ysJK5xQN4rNd4Bs+3eRKehHusUnB8b/IOq8t62k5Y7/X+hf0JelISjhIxgoUxFkzqzkuTT2JKkSItH1acS00g+y2XqtR21bTelObsnmKt7nivVuV/AXWy3cTjw3sxu3zvq/EcELBiAl1KbV34muIAj5MvBlabnw/P0rcwYGXxPL8f+tQp4m12pQiZIXkrQWdx1D1HnuGl1XDHjPPaU5S4U95r7Zrd74aYmqu+kfMxOYdU01QdBiF2idCW3L+uZfSDjawt4Jzx3TNssXfwr2P+xWXDLuu84X5AQUEBt956K+Xl5Z037kIXuvCNwG55D4QQeUKIvwDbgI9Q+kZbhBCPCyEqHO0mA58Af0IJ5AA8CS6/2TcWUpqlwByGT2i6XX5UCNuxtTeRptRmONPZ3EhZbKRMCrNNRT4Rbtb0q2JaWgmUjpCq1JaK14XtJJ3W8gH9+Yxjdv4nrV1k9ZHcJy7Puh8DjXzT4VDLyoxtfrTgHwBUJvLwJuzz1wwDYXip27Izuazv5s0EWjJnHZ36xJ8pbFCOCEMDTaYHJyxSmx5zk7mOnKdKhUrHD7KqTOPZhghjRv8Hw3T6txXak3/da2eFl25IT7DwEeVG+QNO/e9f1HfNPmZ+aRHP1MeIrFaDtMO2vUV+dzuzoDwSoWj7dmrXvJC231Hj1CugyuOlIZrLD1+9jaqDJnCW6YwuLAqmk9q8Gn3HVLuWef06g6d0Q09IKraag0cz8yGxtZaBH34fTzQfEYij9Tos6XDRve67ssTn5er/9wA//c2PufS3k7nwnkmMO6EXhZXp6i+/nfZb/jFT/d69CpWzVteFi9Qmcs0AvOMwXp97EO3RPGlKa6kYWVvAFVN7py23yo9mGqx2FsgNT1LPheecv2VvNP0WmP0ghYWF5OTkuMqAWPj1qcNZcYddcte6o62j9woFKPB7OfiYXvTqV9dhn/YWAmEzuGIFuIqta7f7zm8hBHO6l3NsWcY55jcCX4Id3wg8AJyO0ubQgBgqI+0Y4HEhxNNCiI48hQawqYO/9uyb7jvYz4cVCJd44jHa8aFZCpVfYjLq/adey6nj1GV1EsA1Ep3a2t2F0/ZnIrUl4pnVMZz295g3X3Wt27Kllt6xGvSNowHwt9kkqA3bxjhaCrYuV+vuDP6aQENdBz1V12FIopZaw02qsmTjWxP2u3Hpv+8kNl8RZCqaWvCnlOYuy6tNGw/lmNluZw84m1FldkkuV3lxx/jv1JNOpnv37lQWqt9q3LCe5O3YQk5zA+ECt2O7WfZNfs5EaqOglrjh+K09XoTXS6S7IrjrpjKZjKUHd/pHgoSNNiiocy0XJsHtilHpRGgLfotYrXuouHEMxecOytq2R88C3r15Gt+akV5u2gldU9faHwrz2KXj+Ov5Y9LaRBNRmg3Bey27pr5SXFxMJBLhsmGXMb3bdI7oPpMBA+4kJ5Lel6tqy3jnoANPie2rgmDOrsU28/NHUVk5e5f3O2x6Dcdc25WhuZ9t+dfWjgMYwgoGq/8eU83XEBo+mSCRofTg3sIn8y+hMH+ja1mTz1bzNgAjLfHMht8R6N7Z2jnJNodGjor9O+v6PjtXMmnRh53ux8JvuDBZrtsqtfL2W7Ope/NHAPjMc0mqwwiBgWSrnh70dzoftFj6NZeJ9HH/IQvsa9f69q+Ir3kHj1/S/7zTk8v1sjLahMayxrkA9PDYiWD9Vy5N2+ehnjMpLp5CzzO8fFj1HAhJqP6J5PpQQlK+SUl8n3DTDzhr+jRmVKtH7qSTTuLMM88kRDsFDXFK77N/u9/278bhtUrxqzAnD+H1MmniB5TfoMZjeiKdyJeqYArQZt6P/kwkJkMpqqYGjT2GZOQKda2cpLZMNA+fud+ow28UmTiBiltugbrx0HMKHHIjANfs2IYAQrW9YOp3Efk19Hr1Fap+8Yu0/RYVFTFhwgROOukkCs88g14v/S+5rvKnP0GY5czGjRjBueeeS9Cns/InR3HBxB4ZeumGRWq78pCe9CjJImv4BZCbm8sZZ5zhKl++z2D5D+LZX4WBgUWUXDKEnLGV1NTs3wSt2tpabr31VioqKjI32A2lNiEE1T+ZSO6Ubjap7Ruo1PZVm5MLIWrNftyCUnMRqJoJo4C7gHeyBfL3F1QdEkVtE5pASFOpLdHxEEOaE3YhNAyzCkZ13wIQWvKdaZHagq2ZS5LvjKrSvamkNgm0d0A69zmI1oV56+nLIno0rHW1qXeotzoRaVdjAK8Z2BcIem9Zx9mv/5tenqVJ29u8Q5GjPSS48O3HGb90PpNaPwBgJk8k9zeK9yjbpMpq1zUb5Ht0rqhWPsqS+g9cx/44oojCj9x0BX+44ybeGGDbjIodHSvjWWjV3b/LP2b9g/dOT1Fb9ysS2+KSbmheHwMjQTZOGcZB+RFeH9OPZRMzJ7x2H95xydfdxeVTsicZd2EXkFRq6yK1deHrha9CnFyqiYFViuEUIURdhmaXAxEgAXQQWNp/aHxLidxdGbs7o1JbNpGTvQlfAn5d8QgTVtmXZINQ5HFrip5afhTg7J7f5em197G6aQHvaI28UdqNvCO6Ewwov+WYukJevG7SPu9/F7rQhS58XbHLFkAI4QFeAM5ATV6F+aehJsEvCCF8Qog5wIvAQJQv9u/AECnlcVLKDzLu/BuHDEptaO6SVPtCqS2lTGVC2A5j68g5uZvxeltBc98aqaQ2A42WlFpiIivVbdexTOx6Fu0Jje8jgHEN9sS3pFFlrMe0jm9tA43j3/kv4zb9hVk8nrHN0PY+nNo2Hj9ePIb92+jSwBfNY8B6OztcR0dmUFsrMybTs+1wZtS/DkBCgOaQvxdW3MLQmD3gBAq2D0uuc5bg8OXmoAfGMLhCbfBhtIicnAHIqHKAV/QvoHRnnIMWKgJatwEqEF5YvzmtT8tf6EP3/60mf/smuvs1Krx23fmRs+qYfP5AxvYo5FuNfoac/AdCt71BwVlnqv43tuENu50UFWYN9ioh+duQHlxWpHxZazDIndaNiqByhNRU59Le7nZcCCHIL3WTzHSvckJ9+7EdfPvvb+OtrEzK+UohyD9mLE0vfJf8o8fC6f9nXy9fegDk2NdeoHTHdjRdwxfMHvSeVD2J/kUq0GDETSl+j1upjSs/TPYPwOPreJ+7Cytw0RbPnIn5yNAe3D+wLvndGjcLISi9fg69Xn4Jz7CMSTe7DCGEi0B3ILgcfGY2d6zdvO9m/RLOeIzx415l1MjH9nj/V3UrZU5dxyWZvi74kuy4B3gPuAzoKaUMSikjqIn8n8w2RwAd6VevkVKWd/D3+m72aa9AJuXGze9S4o1HTaU2Q7X4khx3cVMNZJtfva+cWWw6Rhqp7RD5PzLh5/KK3T62hzjbtrrJykYicxadk7DtbPP6a2fS0lJA0Ag4ss91fG0qaL9k7cmU/MBUHZOCnXnfZ8jb25lbtYHQjv70fPnXGY8nshH5sW2uNMliHr2AeFs+a2OwvPET5u94ndaFE2FdFTMXrGXW+y/j1bxcMvRSdFMBYM5SO2vv+tHX8+fD/8zRRx9Nz6Iiav/2cHLdhHl2zeugXwU6dFOlIpEwaDfVUQMRt2KGUzEoU/lRBhyLL2xvY5GXB/S/k4ED7qFk2pmIQID8E7KUZ7z0bbjwZfcycx8eT/ZxqTCD8dnKj6aiLDfgyn638JfD/+L6fs7Pf895v/gjI2sLmNhbkRCDmpZUUBtU7CbPWXa8M5SGSrlnyj1EfHsv+L23cechd/LIzEe+7G58Ycy8YiiTTulDKHfvCneMP7G3CjR+g/El2PKvrR1XUO9VzZzrTj5JkYelEHjYt0ptra3r0kp/NdbZl+KPvXzEOuB6OEnk9S0l2RuaiOFl+vZXs65PJLx4jMxqp7+WF6Yt8xJN2nErySgeD+BrriCR0Fm5QimAC1cagHSVC7XgLD+qOT77PrbtSvPmKrZ8Oiv5vXC7TfSunriNogEqGcrvsEXd/+8f3H6crbR1WcgOTH///l/x1IfuJLjAmAsASFQ28H63pxlbMZaHZvyO0dvUtQ46iON5pWWMPOrY5PdgMKiUrMZdCcV9COWr43YP+jihvJCQ18fBS9YyYYgivHu9BWhtKSo4jnGRX/cjTJKlFRA+plS9/w7Ky2C/shCLuj/5BKWXXAzgUqrLBJ+5j2hHWRlTboJQMQN873HwUWWMPdpWCfCWlaH50t/7QgimT59OUQaFU83vp+czT1P67Rs5dNYsamuzlG3NgnZz/Da15xdTED8gcNjt0P0Q6Dk1axMhBP66vF1SLd1fEAHlv/DWVHfSMtsOLKLDXurQVwRftTm52d//AHXABuBQKWUYCAGnAI3AcODh1G33J5KJ48IktSFBCAKaKilZUHBw5u2s8rqaSKq2abpAOJTaouar2BfLTJDbYAaqC9nmWv4Q5yMzVPCw4HW8k72amkcKB5ldJjxMdCRTOxFpb2V6dDD5Mkxs3a1oVgWNWBShSXt8EbffGZ4YXMgjnBp/ir/JExjLOwA0rguxZX4B3pgi7QUSkoUTBzOpIEDJ6jPpscntd2v0qVhA2Y5tFF40g+dGqD4X1yfIacvwQF+/BPmtFUwN/zK56O1+cwmHw3Tv3oHSzNBTSRz9W2JjLuWnJ7hV1gO6RjjL3PPgE0/lwt/+Oft+dxH/78KDeP1bU5IJD134Ykgq5+3DMXUXurC/8WXYciFEgRCi2PrDjuuHnMuFEKkThbtQ5PYQ8F8hxEhzfz4hxKXA7Wa7e6WUi3frQuwjtK1ciZZIMIr3spDa9r1Sm8+Q+EWIuQ472p6skGSOHTIkwG32bad4YHdiMsr1hqTNp8bJE3oV892j+nP/OaPoVZpZHbkLXehCF7rQOXZnZH42KgtLAC8B3wJuND8LVLbXH4E7ze8PAX2llGdIKT/bm53+ykNKDESKRKlNcZMAnn2v1JZwOdHVumHDnmPsQY8Ry3c7xmOaO3gax8NFPOha5mnPnEG2rxCMqazZeMKLP6HOxWeWaHmyumNSoIHGoGiMw7Z9TJDWtPU/ktcTbK4kjHLUHfK5TeDL396HSINSi4otGM7nCyZSvTNzOZehC/7GiUW3cOYW5QTouTFG44ChVG09m7y/60kHnpAeSqoKXWVI108bkfw8ZvYI+k88npF5qgzqCX1OAMBbrkhXBT3z+XevOg6d10q3gUWU91S/hT8W4zj5D1ef7pHn8qf6UwAoDPjwOtTTfBEfvUeVceTFg7nu6P4EqwZBSV+8ZYr0k2hpo8cRmykfaxOv8srsazOtKJfSsPveHTihkl6jShl+WDdaWlroDLpHUyVWpCp7WXPvH+0a9UIQ6NuXfh++SqCfW1lFz1D3pvLOOyn99o2dHtOJiFnao7g6gnAqywXUNe09uoyDj+vJeXdNzLT5F8b0WlV5qTJSmXH95MJcZpbmO5Y4SLEeD95smdN7gGE56redUvjlDbat8qOxNjPIFsiFXtMJBCrJyxu2x/u/qWclN3Tf+9fuAMWXYcenSinHSil/L6Vcbi2UUq6UUl6A7Tg/Qwjx1aoLa72/zQ9SSjyxGO340YQq7y33o+PuvSf/yZL33wagPic/ufyXzOFpcUzyu0aCyR+4nfpHkq54CpBDw273w0OMxkZ3YDG3RdmFgdH5yWVHvP+YK4Zl+NOVMLQUmflwUy16LIQWKMNWdRd4AxFKYgbf37YCAD2aTVXD4YxY8ATvbPrYcSzVm50JZVdLi5RCmyEE7299hqiE5lgxkRdHMXx+iKrVK5FSUhoq4wQeBWD2hnQywIgRIzjzyisJjbQzxq989EF6h9Q1sYaCukf1zUhIRh6pfq+8klLXvorCPp5ZodRvMzl2EIKTfvBzxp2kVGpK6pTCidebS3n50fiqq+g392P8vXplvjxlAyDkVofLmW5WBfR6CegBZvdJV9Xy13ZT55CiLLe7GFLiDlYUVdcQyst3LVs6aTBvjlXktTx/Hm+fqu75Y3oeQ4+8zhVdvio4vO5wBhYN7LzhAYqcwgCDJ3/BIHcXOsP+tuVfXzsOSVKFRaDWzcQoQwOfNIgn9p0dj8d3pi1r8dpzj/9Weol3oNSmk+BM+QAAUS0D0TkFHuJE27ML6rU05+NxKIZN3fpa8rPX1PUasmVhcpmPKEbcVJp2dPNf0R/y/lPT2bChL1KKZGlxISUJYaB3EIQY9+abABT/1EP5DV4K7rfPa+Xzp7JtwdHJ7wMW2lnzOVXtlA5RpLaCsE2q0nNyOP0gmyQVMI3u6NgbDJy4mlFNdvk0AK9fjQHGV46nd0FvbhpzEyPLRtIYUnNY/6YlWfuexGE/hCveZ9xvf80xpfn80UxKMtpaKWhpx5fBVoZH28qu/x1lqgZqHvJm9iAyoYrgQEUGm1aUy8Ypw+gRSvcVHX7ZtfQafTDFNW5SWKBvX+pOVeMCp1LbE5ePp/Dss/HW1JB72GEA1JnJaAWeTu6n0x4lOPQIRhzVH493z4NK3rIyis455wsRtiyltpxdJNYfkCjqCWf/G/wHLtk+E3w1NVTdczdVP/vZF9o+OEjNF8ReTBT8iuCrNic/G7AksU6QUr5obmtIKR8FLjbXHSnEbpTp2MswhPKqCzSE0NCkmq7HmyEU6oXXmyUpwrCU2kSy/KjQBAgNA2UT4+a7KeixfccRac+TN5qktlSltufFkXQEnyPh2aeZJbuFbYdlUzlHb9zAT+U1aduG21upM0qR0iA39jkhzSbFC02im33XTLJ6w45KVwk3J4d92VO1rHurPElCt87Xb1aQWevbhKc4yNze6h21JVRAs89UAFd6eOpYmsHk0zLMMyOliFAhl4y3bV08J84NN9xAOBxOb29B09BHnMH3jxlKed6ul2vTNJ3c4s7J/p3h4J5F1BTu+9KjX3dYyeJacPdKwHahCwc4vgxb/jGwxfFn2esbUpb/xrmRlLIemIlSlBsAfCCEaACagN8BPlTZ0Wu/YL/2OqRQ5HQhpCv5yUJiLyq1pZbQtqBLWBBajkjYycuG7h6zyixzl+NuvIVB373XtUwIwQUTe5Ab2PtCNl3oQhe68E3C7liA2ag54b1SyulSyruklHdKKacD96MM9FnADtSE+RznZLkLDsh0pbaEITkxoYKiVZtWs0/KqqcoxiTM6ScAQtKrt8rSEhmc53HhNtoN5KVlnO3v3KWijWpCvGNHJZZ4mC+uHO6/790xKTAeU87uyc1teHAHoa9+fh3TXrkab7udSVzYagfIg6359Nmifit2TGTMxx6Gv/tmcr1nk30lPIk2yn2LGNH4Od97dDvFjQY1xSH6nfR9es+6MxkAEFIjryLChDe/lbG/PYaVMOOCQRSJZt5ZuYbLhqq65vnH9KT08mF48vxJlZdAxGMnvQpoR12L415+jh+tWIAAvGbAxOP1onnse01kKmUCFJx6Kvknn0zROeegeUAU1VC0TQUBxo4Zg9frpW9flS2fF3QPzoI5PmZcMIhA2EtrazqB0ELTuoPNPkB130J8Phh72XT8vXpx9/CTVH+7Z5B9P+MxOPR29EA6qS1v1kyKzjkn6zEzoW5wMcffMJJBh6gSciVXX0W3v9jqMZomGDGjNq306J7ilL6n8NrJr1Gbu2vZ6QPGK/JbWffcvdoPJ4bnhlg6cTBHlOTvs2N0Br/p5O5Sqt8r2O92XEr5cidN/uT4PCprqwMQ0pZoM/8Z+GJR2ggihAFC7tf79vW/P8i/71Ilv1qCyuHsMWK8J8a52ukY5Mea6LdxRXJZppKhannHih6Zt4nTHnU7fwdsa2DGp+8yq9Umz91+sB0vmbT4YzJBpIwsPPEIhdtG4fX47EQAqcRl746dyPD2IPme37LT+BcXPVvPL7Yp+1fXtsa9X2+C6OKnOXiUba80kzw9ZfRos5EZ4ADO/e1faO57BqMunk5lpI3Bn97LVt9LSCSFheM4hn/x2nsf4Otk6JaXowjCHsOg3G8qzZnr6garwF5uUYAh0w9nzqNP4Qu6r+OJI6v555JjOP/5X2U9RlFVDQefcCon3PQDjp5zU8cd2gVU/vhH9HrlZTSfj/fPeJ/vH/z9tDZlN36Lmnv/SHBw9rKjuwLPLpAydCHQHY6jiC/C8yc8zy3jbtmjY3ehC18h7Fdb/nW242CrrmrCJhKBrdSW2Mfk9NTSKb8Wc5Kfo4HttHraqYitz7ithzhlbAAgpnXuHG+PBli/ejBzEnekrXv9tdOJRkPojii3MwFPI8FvH7mGGz93KpUb3P1xC9M2xsiLSQ6JDuDY9tGM6T0BT5MqSyqlxnncy7gV71G1cwvNoh1dZvcaBFpVUL/toMPQmgW6lPhyz0fzdEfzutVcRvf4b9r2l0evojBkk9osJancwkF4w8cQCJfxK3kRc2L3ECyKwUWv8thAe78WqSo/kM/jRz9Oj3xFlg7lqPP2bV+Vte+p8GiCPw6sY4iZJBTfvAUAb0V6AlOgvyp37S0v5y+H6sm+6GEv+TN72IptHaC0rgfHXH8zegZCWiAcYc6jT3H5X2wF0GE1+fi7d6fXC8/jKVZjkMu6lfLnQXUcVdJJsmL1KDjhvjR1/y8DllJbTpeSzpeC3COOQM/7YsmteYfXUfHdsejhb1xw76s2Jz/b/P+ylPLtDNs+AlgTy7O+QPf2GEptzVZnE2YwXApBe8NWNKEjZeb5blKpzVF+VNPUPiwicMx8vYSDiqQ9Q/6XEHbC7saARjgRI0DmqgvZEEk0Jj9bSm1e56tMamhSp5o1lMkNdJMrk6sCMTPInoiheST5vt8l1zmV2jxCtWtvVc+pNe//7CG7SorfJB3VRNT83BKl8WnKnka1GOXXj+L44wYktykdoxK2pJRgKtrllUUYOKlb1vPtX5Gb9Hfq2r4nIlcPGMT0Cy7vvGEX9ikKzjyDkmuupuCsL+X10IUu7Ct8peLkUsoPUWpx9wBLAC/QDLwBXAgcIaXsuF73fkRbWRVCSoQwsiq1hWTmkuC7C2cJUWfVrGXti1jj34gwbFJb3LRdVjhgXSCzMIXQNCb0KWVs90K+fUS/jG260IUudKELXwy74/mxMrN+mGHd7Y7P35ZSZq9r0QUwlEF2luuUEurkCsrqt+I3oslJ4d6ENCQbxA4+1VVw18BI9iEQaKaiInvmsZFCYNtIurKR7ICIp3VyPue+8RSXy3s6bJOKgp21vP7amTQ1FhM0d2+R2iwcvDVOTVOcSrnWtbx9kyIChbSdruWzV0ep2GHgiea7lufpdjDhmMuGIlEDGun10WfWTETDeoqMHN584xRKfmw70gN96tL6rTsV8pJReR3h1xky77209qkIS5l0uGs+HV+NCpJX9y1g3PG9mHRyH5ykSDFXkfP61VZx9uyjOX5EFecepJwVus+HpmvsjHccsNFCISpuuxW9pALOfQY58nwGfXYf0/LfoaKqnJtvvpk805mZG8zulJw8eTKlpaVpy6dNXcaA/j8nEPYSCHsJ5fq48FdT6TZ9OACfBz2s1ROMOnVI2rb0mg7jr0Ibfzl9T9zQ4XnsKip62qU9ii+9lPDYMXtlvx1BCEFBYNdLanUbWMTlf5hKTuG+zXaLfMlZ7/llIUYdWcdhF3x1FWsOIByIdtzp+f1KSSwYybKYdumcYFsLDeSZ5UfZL2zMjUsXs/rTecnvG9a+RO3RymbFMwS5NRLQlofuUJ8xsthvH1GOkJlV3ADKZPo710OcWDTlvZTw4a9fguGwudU1A1nern7yYFT5Tpqe8pD7iB2MjWWpRyQQ6PXQsraQRQsnognBrxLHc1npX4l4nkGymbL6BBUxjec/vIC/L7labWhl+AkvFT+5g/Kzzkju85i6SZx99tkUmcFni9SGgMLiIr5/2zEM71eKp7SMkq3zCMbU+mCwGxO6f0RoR9+spb8sXHTWWcx68t/WbgEwzHMcdEgV5/5sAgXl2bPVtQzEc8/ieu7sU81n492EsrqhIwiE91zxQ/h8eMvLO2yjBwJEJk3a42N9UVREKvDuAqGjC134muBAs+VfWTsOdna1VX7UIs0qUptBPENJkb2JjrLMJYKYrxWfljm+oBPHZ85JW40wZbFNHR4rbnjxxXJpfiOTY131w1l+1OmrCNCG3OmhtsmtwDJyh85P57Xx0dbn6G1UUCxzqZ1wLJ6menIWfoTXGyRCE+M+eTlp92QG225l4P9jguTBe49m7G12GXFNz8OXcxxCuMta5nZz3HoXvMQPxKX81ziIwoiD1Gb+nuf96kdccnU5+vCzKWIbHs08z7waDirI4YQ3GxmyInscZ0Z4Lbfc9wvGfjaPW07/Yre5NJO7PGXpc2GLtJbp2uxNCE/H7j9dCI4oyT+gSlx2BkupLferrNT2DYXQBHrE13nDrx8ONDsOWWy5ECIEjDe/PpNpQ6lYYc+aXw/bJ73rDBIMIU1VFw1N0xCmUltbtB0hPMgsPulM5UdVsq9GwnCT2iybq2G4/N+bAzo5sVhS1XRXMS5gcw09pkJbv4EO/mE8jrFuLgB3cwV3MIfr5Y8YvGoepS3qJzNatqF5jWSytt7ahCZsUpvRruZInrZCZsZfoAJFsJ5eYvv/rVLaEY96HhPW+eru5zPi93Du+Dr3Seym2brlYJWIZI279iVOvuUnDD30iH1+nC50DM3no/iSSzKWJ+9CF77C2O+2XEpZJ6UUu/B3TpbtN0kpr5NS9jHLkBdIKSdKKe+XUu7bSe9uojWeMEltMqO/uo0AraRX6DhmbTRtGSh102zQHKfuVF5LmKpsVTn2HMMb2wiAP6T8tpv92VVBw34Pj158ML1Kv1pKzF3oQhe6cKBjd2YRRUCLlCnsIEBKuQaSaUr/3hsd+zpDZig/KhEIIYnk7CBY1ebWAt9bSEj+6/+Id7yqPHoCQ6nJAAUF7sC0EB0ffwPpTPRYljjGufJevs93XcsqW9xjJX8iTuHncNr2tzo+B+c2cbuPYZOUldvonlGf9dkm/vH3p6hlpXv5RpVlHfFsdS2/8fP2jMGFCq9daqX7oBKqihWRrE9NEfnHHku/zxcwMzqC2S2HIGL2udU+8hj/O9ldjt6Sk/fV2opcQmpoYQ+ik2znX8SP57bYmRnXCU0w/LBu+EPuwG7IzIavnXkUnpwId580jKocNTDTPV40XfBGU5zYcVnKkaWidhz+AUPQjTgV4wenrc7xZ1daqaio4LLLLsu4rveoMs7/+cSk4pwTMQH/LydKYQfBfg7/MZpH/f6Fu6nO1oUDF0IIxh7dg/zSLtn/vYAD0Y5Pdnyen6VNiRDiQyFEkxCiVQixXAjxsBBicpb2+wemubHeWP0mHEK5kNSTb77n949S299uvo7/u/3m5Pd5b/+IONkJPoGWYoyED90xcQ/TRHnCPQ44SL6BAM5IKTXuRNCRod5n9WfMkv8iQBuG4R4PyISXtZHVeH2OsYXuo8W0T5bboG2BTvg12wZoMrM98XsEwhAU/t5LItGdgjJV5tBSG9WFCkAYcYMhR91K/jF3mVuaZIWoQf6xx6Ln2KWVB04ZRvfu3SFJ4rdL0TjhMcuG5bTIZBAEi2yWRe3UQqiggJAZ1NbMvlgiQEIIQrmdO3qfvHy867tnRRNnVhVT5PvGlW7qQhe+qTjQbPlkx+evlh13wLI8Hl3ZAEOAR+47pTYrbpDogAeoCnpp6CKRMUHMQxw/ioi1cuMg/EY7g+Xc7PsTgpD0kUkRvjKukpO8CSepTeGQptd4+/VTkU3pYwuL2O+Mg3hNlVEtkUDTlGJqKDqK8M5qDhs0gTX+jWn7aW1VCWcf9TSIGR2TAo5vGc9J7ePgyo/shdUjec6vuBSFIR95xx7r2kb36viGzkLzqLlkMmChe9B0wYC1MY55L3u2f64vwuSP3sUXj3HQEed12L9sqPjJHRRddFHGEuClEdO30NbO1JqpX2j/u4JsquxfZVxdWwZAqEuprQtfHRxodhyy2/L+2CbSXa/ZDWtduRAivcbyfoC0lNrQEJryt0shaI/HER0ptSXLjzqU2nShvks1b9tpKAKZ3+T+CdJj/7nxzkltoUQzFXJd8nuNWJ38bFVy8QWa7L5JidzsTj4fzkeIpr9Quf6ftH70Z1rfugehgY8474SXMu2lVwkkYklSW2xpHvUrD2Lr/OMZdsatfDT1YQAG5ipyW2npUcngfL9mVT51SLmyyamkNoBbZg1k5U+OcvRx93gQhtl+f5DautCFLnRhH+JAtOVfG0gzbq6qiaXPX94Sk5AZ7Egos6nHG8+yArc6m5PU1hQ2lYgNO/HpB8Uqmfjk1i0ddb8LXehCF7qwD7E7swgf0NjB+kZQrO896tE3ANKcXDuzn5EaINFFXJUh2QcE+dTgekIYGUuNAiwrqyDWgRz4FiM9w7hVyxyMzaEhOfkH6N7URH5MHfdyeQ/XNv4cgPimQfRcP7zDcwDIkzs4e/PnNCd2kGsEGRSvIZSwSG3uWzr3xZ+RyP8fR/BvvLKdM15p4JWIxnlzrlTrG2JEIgNc2yRIDwwflPOw63tBRKnQFOeqrAAhBF485KRkCWihENP6l8GAY5PLLKW24LBh6Hn5AJReNQxPfueKWydc91suufGuTts5x3sXf/Q2N/eoYFZpfnJZt0FDAeg3/hA0TZAAjN0opxkaPpxer71K3qxZaessJZnSnI5LwH4R6J054k99lP6PfJ+yb9+414/dhS58DXBA2XEhRD7wHfPr61LKRVmahoARQBQ1bukOnA68LIR4QAjxpbB5rPKjwgx4e31+BhQWUZ9UapMY+7hsmRN6IM6QCxZCcA2xDHbMgr89jwSJ5MT9cPkUeTRw884fJ9tUJdZyOb9Ifv+VvCj5+c/yVLo1q8Cvs+xK6cb1nMLDyvykjC3erHyOBZtPolehoxyJ7iWccI91DOF2VxhZzqPALC1WuGMHN9xwA6GQCqBbwXXNzFQ3EhL6z4QcFfAUMrsNCVWo7DmRdIzYSm1OeCsr0hZbQeLOlE2EoyRYskx4h1ukY2hNPiNrd13Vc1/i/AndO2/UhS50YW/jgLHlX3U7Dg4BT5PQrJs2QApNKbUl9hWpzbRTnZDa9EAbXhFFJ53UppNIqsY8PWAiq/3daCF7EogUgoDMTHpvXfo6YCungq3UJlFlRAOx7MEA4Qgq6AF/crv+/e8gGOyOlIMJtfVgwMxRJITb9rfEAixaOAEAQxjM7jM7uS4wKL2s9ZsNOp8G86CoJ9/rWckdfRSx/a/nj+H2YwcR9OlU/uQO+i/8PG1bzfRXJIcDmneXiF4VEVul/rpR13XaPhP83btTet21GZPY8nJzOPmRR6kTgl9M+QWfnPXJFzrGriI0It2X81XFnO7lbJwyLFlCuAtd+ArggLHj0Kktd2YzryM7nOsy1+LalzBV2azyo2gahhA0+UNELVJblsTxZJKSEMnPmibUd9MOftKk3sl+MivAACyO5OHphNRWpa3hZm5Jfi+l45/Yl9DRMoxDeq0fz4S2VuKr30a21bMsrmzU2kQxBS1toJMktY18by4b3jufRHsunn6HMmLSLBh4HAKY6LuAQQPvSZLahm1Zw/zxAzn0eOUj92Xx8TsxoHgANTnVnbazkDDHP12kti50oQtfcRxQtvzrBolMzkWNDugLqSVI/Vl88FoHcXYtaza66ReQkgFvvstFD99FSAg2ThnG+LadAFw/XgmWXNWtlP+N7pv1GF3oQhe60IW9h65ZxJcAKQ1HFpmC0DSEKZcuEftGqS3FsC/VNyaV2pxYRk+e7zuO13sPzbqrp/Vj0pY1aOmyr6Cy2TzYTvA75i7HYx62iC30TtiZZ7rZxd6b1mQt2/Y7LuC0nXMR0uCk6DgOivdJMvFlSiC9pGEbsiZCT5bxIKfRfVOcurJCMAl7HgPGjnGXVktkULgJf+sdytsdLHyrRIgjm73kosEIbRkAZc2L8Ycc8ZmT/pL86AnZZK9InnIWePM6UCBzoKYwRFnu7pSbFOSGg1xZW5YspwNQ3K2OOY8+RVXf/mjmuRidlCBNhTdDGVELT105gf9eNXG39rcr6JTU1vdwGHbqXj9uF7rQhb0LoaKffwUqUOVOrsjQbD1wGzAUCEgpC1GB8fHAi2abc4GstauFEBcJIT4QQnywZcvezaQyMryOCoB2ESBuOWn3H6eNcFkrmi7xhhLEyO6APnZtjIQwkhP3EMoJYCRsm3XxmwuS2eIARWxLfvYR5cqlCwAYz+vJ5ZqRoNfLv+Htt2anKbXt8G8HI8jwvt+zF+peRra7S32lXtOPhWCeL85bfneAYExdId2ffIIeT/9X7SpJKjP7Yiq1JRJWQF799xSHCAwoovj89CC5bhEbLIKBOT5K/Znzjj2W5gtP4MmDNLtMWFKpLW23WWEpinyRgXjMQQa8dHLPL7CHvYPvzRzgytTvQhe68M3B/rLj5rH2mS23YL3GPeYcUQqViBTfR+T0aFQlfHVcflRDeOLoJPBmCKTHmvy0rHaXh15HTfb9CY2AVOODa3fezXXyjuS6uIzSuynisv2WqrxmqqMXNjbjSbkeZdePYumscvL7jlTntfwldJ851xVQUjyNg8Y8D6byan4gn4lVisBWWKjmivO2DCQeV9u8cPILHFx5MAB9P/yAur//LXms3GI1BzYgSfG7vFsp51YVA9CjJMKZB9lK6Jmg64r0V7DTHFfou1a6ekbtjF1q90URmTiRogsvoOym7yCE2KflP6vumEDB7D77bP9d6EIXvjrYBVue4/jcQnY41+VkarBvbblECqWgJoSOEIKGgI+1haW0JeJm+dEsSm1moFtoIqnUJkylNithqt1URfWZ/w00V/lRC16yk78B/LSTQ0PyezEdXwefoSEykNqWyUqkY+J8fe6lHNd+G007TKVPnSQZ3pPIEFswfRU+PQ8h9CSprb21hRKfbRf1DhLdrYl32BvmN9N+2+F5OJEwYx262PWk6i50oQtd6MI3DMJd4SwbUufIvizctY5mVk6lNgs161dwzHNqHur3aOSu20Ze006CObmudkGZYOOUYdzUs5KBkSDDSoZxaO2hnfa7C13oQhe68MXRVavoS4A0FKlNcwq1SVV+VMNQE2Qj3qHB/UJwOKFbiRLt8Rzda9OzgKMop/Li8m5p6zrCTi0zMctPu0uGPTfmR5cW2949kR2zTU1wB65fwbq8SloC7vVTNr8CJSBTyqOevSLKWyUeum2qdy3vd+h6Ggv68/rL16N7lZ/FU5BnR74zYHbh1VA+He+R3+eX93/IGhLcFy7hhQ8vYJOvGKZ8iDDrquMILPt75KOH1wNwUP5nVN99Scb9l11zZfLz4EG/paHxE7zevau64vEqJ0V4yEAq5hzRYVvNjOQbib2nDjioKm+v7cuJr2HFlC504ZuKXwIzzc+XSynTjJGU8nng+ZRlCeAtIcQM4HHgGOAyIcSvpJRLMuzjXuBegFGjRu3dyHSy/Kij5JalvqEpkrXcH/VHU7CNIn4vrs647oPnVCLhX/1LCbdXme1VMDiR8FBev42AoXFk68Es4o+ubb+98x8E8j4GoKqtgW9/+ht6DXyb+1AlpUOtLeixCHE9QGNDgHlzD6Nnr/eJRHYQM9R1KcrpDsxL65eQkiDw3EjBiOX2NfsXkpaQGj+Ma1cOdo9fp8eAIgI5tmpKGqnNDChYdq0gfywV5cfTvftVBKdkDvhbAWRLbcZS0Uk1PMLjQZ5+DO3PPZkktQldZGybCaXXzyEwYAA/7VNDj6CfSYUZ4z4dIhpX53XN9N5cM/3rFZi+ZOgl5Pvzv+xudKELXegc+8WOm9vsM1suk69vNefUTDtuaAJN7jtS2y9+cTejx3Ss1GagkUDHS5QgrbQQca3fsa6CbWvbqMjbyoZ8Zcs9WQLqg9Yuo9+m1QRQc7S62GqKWYMuE1StWwnAxjWvQP9RyW2sQEKL3s7419+gcMcOV3BhVMXTeIuDTC7uTWMiSP3TK8g77lh0n0mst+yqaRuDOcqO+8wSoD6vqlBXU+hnhblPj0PRVAu7fQsnf3cM913zGpA1961T6HqQgw96Ef9dw8yD2Mfzh7O7xvYVyaz3W28iY3GEx0PpnDn75Bip2JeEuS50oQtfOXRqy/cW9vW83FL8FkIkq0cAtBrSLD+aRanNtPNCaEmVdU0TVPUpRCxXyV9xoeajVgUSmYGQ/oP5H+EZlFmprYdcynLRizx24nEor/o6UH4D0Bolmjnvs2IGAOt9PdhUMRPPglf5/eBjWBautqTqVFuHUlsigzqoRWqziN0+s2x4tLUj3mJ2FHjVWGZiQefzWmv+3KXU1oUudKELXcgGZdM7V2qrF+54aiqp7aBln/JOz0FpSm396hMszDOV2jOouA3/9B0MsQFQMc6Dzjudvg0jGDRFEdbySlU1kNziEtd2fz3yr52dWqd448YptEb3gdhNF7rQhS58TbC7pLYyIUSHb9VO1ksp5TeeSGdkUmpDQ9MMNAzieDCMtg5c3F8M0pHhFRcJajMQ2sAu27W7iGWaLAMF7HA52P2JUFKRLYGOnlAz71YDSuOSS159AoD8ZkmLQ5TsLnkF/f65FREOUFh5OFuX/J3IgHMBGLkjwY8f+A3rC8a4ju3LSVCQl0PrPFsCVo84AgITrk3rb3GPcjjqXBJl+TxgZuKh6ZTEdlIS22nuxAx6pyjqaQHVYU+ZO2veCW+ePdH3enMpKpzgWv/5hEHsaaWbwYdU094SZ8Thh+DtpKzomJndqd/cQu3g4j076H5AlxO+C13YY3zpdlwIcRd2Fvi1UsoHdncfUkpDCHE9KhiuAbOAu/ekX7vdB+t15Hhf65ZtMM3h/iw/KoTkRWbwZ3FRp23bRYzipp0AFLIdAENqHDv3dcqNfGBksm3t27fiaSskNOSPtLAYACkMhHRnow9c/P/bu+8wScpy7+Pfp6rD5LQ5R5YMu7CwLEEWUKIoimJAURFzzllRj0d9PUaOHo8RczoqJpCgIEEEJIdlWWCXZXOamZ3Yoep5/6jqNNMzO6GnZ6bn97muuqancj3T03dX1V33cz8szj2RduDALGyYzLbMfR2nnLmcSNhm71o0C9jPaa33cdO0kzn/hr9y4umn8fyZDpd8xOHi8O52ssg3oTd9/fR+47K9xmCgqhG3N6zUls7cmIhyxBFfOmi7ADQ3nwzArFnn0jzb4cQLl/abJ+r0qeyS7b7u4DFq2hVXAFALfGzZyHrnyVRqO//oOQeZc/J528q3jfcuiEwG4xrLKyWOA9nP70zXhZFwhG8MxqnCK/LkdimkUsE5pjfIGX+KCB4uETxq6M6rmRpwUwl8B9y8fUwPcHnn1KceBqDKBhfeMxVVv//4J3n0H4Wx62V330QVMdwFQQJcTxzmb+vf61x147zsaxvedI80N+JGgxhps8nihvPfegwzFgTnwIeuuJLqqgVMm34GO3f9gdMOP4FNdwffRfKT2jIu/cxJeCmfWFXetFE8NFBTsyTbw3gm8e7iDx5P/bTBq6Ev/OEPcBoaBp1nuCItLSVdn4hMGpPlnDy/a7WB+7cunDZYd2xjI9v9aFipLe/adNIHYyL4fqL4omEMNcZkE9wcx2DMATK3TJ6dHZyzxcPrwxb6VWpbdKCraFfhABfye3bYOTyX6wFYZp/gKbNi0AfZd7cu4pjv7qB3UXhT33dw3WD9c5uqaekKar51Rov8WVyYy1Y2s5SqZIL5W//O0ve+If+gw/mCJPSZi4Pz3ePOe0HRfSlWVW3WRz7CLmupOfFE6mJR7jrpcObGD95daUaVO5weSEREJqRxj+WVykK2GExjqgeKdw5GlefR6+Zi1PRE4bl71AuuDQ9W9a1Y96P3H7IH398NwOrZq3jpYYuAXEXwo888h4bpM1l0zKohHM3wzG8e7OuWiIgMN3Aqo6QUfBtWassFzUg0OO83+LTRjO9vKnlSW/7F39QgiWvOMPpLe8XmJL9b5HECd3G7WZcdv9L+mwdM8KT3THbSRe5J67hXzYfWJ/ivY/azon4Dvb1Bwlmqz5eIi//ZyW3Pf4oHTHBzvYoeXGup+pdPF+8Ivs+ESW0AKT9BbyyXsPbr2qeD46kp/OaTvel8Za6q210nHc7W32wIfrniRoDi7b8w6A4lvnw5ANFZs/rMEHZxNmMGAznYTe/m6Oi/z7pRhzUv6H8jvpimWTW89CMnjHqbw3HiiSeycOHQKwH+9i0nc/Pju8dwj0SmjHGN48aY/wdkSlG831r7tZGuy1r7pDFmLzAdGNoHXgllevzIb9BMUlsw0pa1+1EMQ0po88M7ubM62vik/SjLeIpNT69if2twc/rY9CL8vHjspGuIpBpIuz3hClya2w/BVm0kQpq32q/yvLtfyK01/a8y+GF230fOfg7NTUGs33nGymDirlbeuO03HHH7Y0x/spXqs87gJ/HDSG7+BzcmmkjF20gPsXPOzN4aA7z93zj3PQs/b892ITMcdXUrOOvMoCvxV15ZfB5noO5ly/TA+VdftpJv/G0jS6YPretyEak44xbLKymOQ36ltuCF4ziY8AE0160hPdonjYrwfR+MjyVXqe35D97On48tfNApYarZxHKOs3dTXaTXt6jngevi51WkGSipLaO7dw/Ecklt1nMhr+Js9aa7YMka5vdUs3VucEG98Ma9Ye3eNPucDmJzc+fdmYfnTMTgZhLT8r5LLDkm9/BULDaN5cs/CMDxx/2KhoaVwH8AxZPammb2v7Bf6kK4s5cevMp47dq1pd2oiExlk+WcfHve63nAQJXc5uW93j7APGPIhkltNuiyLD+pzYJxXGx6gEpt2e5HneDc0QQVRq21QaIb8MhhxwG5pLZiVWO2JSD95Akc2rSJDTOWFExz8Hkhv8/+/ik+RocNkqTfY7/IZgrnB/jjsxdyTPd3ccKHmXzfzSa1VUUdvI6gG9POWP9z8Pijhtcf923eeOSrWLRzO/BbDlv3mdwMrZuDny3BV6+qujre96s/F22fH5zzA+bW9X8QK750CQu/993s74uq40WX7+vkuSdz2RGXcflRlw9pfhGRCUz3yceIzavU9sbd9/Jw/W/5Oa/hgCk8Z4t7ht68G7iHHcid177ggdtoqw7OV4slrn1sfYLPHR4v2v3ogdoe3r7iCqZVTePlh76833RjDIuPPW5ExyYiIqMznOyZT4/ZXkwx1nr4GEzeBWTHCcqOP2JWAnBbeidnlnq7eRVjEhQviw4Hvxie730bErxl1xP8csYR3B7eivjyfd3MXvV5NtjDcDa8HedQW1CpLUaMJV0+X35kF8+sTbJtw3PB3Uss2cJu3+cicwK3tKeJ+j4f4D+5lN8CYfn0Ptch0vueJDJtOQ/su5nOdCtNvbmnvar8sJS7e/DjWVQdZ+Erj8IO1gXn+56AquDCQ8tll1F1+BHUrimsDFd/1ln0PPQwdev6V5J5/juOZcsjfZ+xH9ysj30Mt7G0T4RPBOeff/6w5j9+UTPHLyptF60iU9C4xnFjzJeA94e/ftBa++Xx3J9Ry1QHy6/U5jhBLpsJnt8ub6W2wadfaH8HPI903nePQwmSubduPQqA5Xuew4L6KIm8E34T3vj23KC7lUV3fYIqfxpn9BzLXv7GKdzOjK7nkZgzs1+MtjZT1bTId466WRhgf0cd02kFx7DSVEFvgrtbjyTWYPnzu9bw/KtuP+ixF3TzWjeTuSe2MOvOB1j7omUHXXZRVYxnegfv+mXA7YZvAtun4stYO2Z+E997TXmT0UVkwhi3WF5xcTyPcTJXwx0MHtYxNNo2vDGI47s7OvnmKS+n1SaoIkgYr04NHIdcPKrD+fLVJTPdoOUltZlov/nyPdV6DzSsyMVnzyE/qe3BhQdYuekx2nq72bn0KGA1jVW5amJOVZyr7u3hDvtXuPiM3IrTmaovDs4Qzr0zmppWF/x+sIe/Dls7m8fv3FlwXUNEZJKZTOfk6wmChAMcBVw3wHxHhT93Wmv3l2RHh8HaoDqoIehq1OR1bZnGYkxk4O5Hw/NI4wTdj2a6LvVSSQxx2qO5uJRJZsuvVv5O+19sfOQUDphe2rYfRnV84GvtGS4+TbQBsJq7Wc3d/eZp82ZywUVf4pqH3wtAKlVFNBp8VzDG4LeHSW3R/kltzVdHOO5t11Nd3cL6zMj8+DrtENh2L8w68qD7esLs0p5zRpwIHzjhAyVdp4jIONB98jFkjclWV+vp6OU0/sH/0T+5LOg6NBfzqzzL0r1pnp4e1F/PJLP1rdRmADcenP/37Zo02IE071j1jpIci4iIlNaQrzhaaxWsS8T6Pr4JLphnmcIA+mC6uuRJbeRd/E2a9MCz7T8cpg19tTVtK3iqKpcWXxUe1qE8zpLdXWw6lIKktt33f5u9i4/mKE7lqR9dRKr6CFqcXhw/zl14zHI6qH7qr5y89UF2X5LbzswnX0D88V8VbLvnzq/jVDVz4skbWDPN8rfOF9FywGN/g5uX1BbjuPu+zH3HvY/BmIiDiQxSZqU+V5XNOE6/hDaA6pUrWfSjq4suvujIaSw6chgNC7S8+lXDml9EZCDjGcfD7k0yH8IftNYOrS/Iwde5jKC6C8Cm0a5vuDIRNb+6acR1IU1wTm3A9wetRF9Sxh34Bu8su4OX8zPgeaTy4vG8+95Nr/UgvKie+Zrg5VXINzaI774bPJnupINuRXwvl0S+re4TcOACbuuTML9n92KamnZRXb2IfmqnwYef5fBvfA/vse8GNx/CiwmvuqyHqmPPI1I1tJq1uUptwcX6WFWEl3xo9cAL5Ll+9Qr2p4b3d6qLBk/7za+fH4zwMzdD9KCmiIyt8YrllRjHIVd11c12lengkMI3YKxPagySp/Ykglj5c/Oa7Dh3kO8LLh5ncy0PUvg0+LTuDjCGGju06igAJl3Y/ZrX5967rYmybOvDbJ6+LFsOrTmel9QWj2N7PFa/8EUFy9U9Zz7p/b3UnTQHE3YBs/DolUPer6FadfaiIKlttKXaTns/3Pej0uyUiMgwTKZzcmtttzHmDuA04Fyg3/wmOAE7J/z1hhLu7tBlux8NKrU5juF1923gh8cdStIYjHGxtvg18EyStDEG69ns+Vw6mQIMVx2S61LzAOFDzuzLJpQv5mmS+5fjhX2jHbl9Ew8sXDHqQ+pMTQfS1J7/Th7ceh17di9h1XHXAvC2M5Yz+4xPsPvLX2Fj0/x+y9Yet4bq6gUF4wqSxi/4Mpz8dqhRF9giIiOh++Rjy897bMsLH7SO0b8b8aRNkp/eUJV/Sm1tNmGtb6W2nro0DUcugq07C6ZN37eTvdNmY+zBE9RFRGR8lKmjJMlnfQ+LKcgSd5y+V5QHTjobqZ6H92ZfJ0zx4Nx81/tx/bqi0wayP+1z+ObcF4vqvG5aUmGuXoQ059o/8Wn7YZyOPTzadgd/2vItkvGzAJgezdWu6z38CBZVe0S83oLt1P3wn7zm3I8VbjydwO/cSXN1DzOqurmg+T9pcILjjHq5pLaVP/h/zNlxZ145FRERKYc+F8/fP5Qb4eYgpTrC6Zn1+EDx/jLGULHbqfndj1osqXT5Yo5xB95Wfhcp6bwk+rq9K7G7cz2+ZY7J5ifaZ6q5OOH3krSl1/6Ah7vytk03FvhGo+X8P/+Fs268CYCdOw9h3emPUF2d3yNNnqoGmqvDGwVuLqmtqdmhqjaKO9QksUzVvKHNXaApGmFpzdATAgCWNi3la2d8jU+t/RQAkeZg+bpTBzhOEZFJrFLjeLgnADhhpTbXrQ3OSB2Lh8Er0h3JqBVJYIt4heNO6C2s2rKS+/mZvZgf2pfzlb3v5TW3/oHadHA+7w7jko5JFt4M2Ne9m3Pe8m4OXXtaMMJaHOCkJ7fxvLrgga5XLljM4v/7P+b/z7eyN8UXH3t8wXrc2ijTLj0cpzqCMYbXffV/uej9Hx/yfg2V45YoefysT8AHnizNukREJoGRxPJQJgP4DGPMmiLTX0quC/Efj2IXR8FiTfCwmTEuxnGCLrqBtDUYE8EfsFJb2P2oKazUlk4lscbwhwW5pLYugmvl+UltTljtNBU+OF6f6OGr9/XvMny4jBNsN/qy17Lp6dV0duYekH7eEbOoOuIIFn7/e6Tcwgqth9z5TxZ89zuDrzxeB7OPHvU+ioiIjIVM9VUAzwZJa7EivY71vS4f923BuFzCWuGc6biPUxvETzfvfD9zr/7UuSeNfOdFRGRMKaltHFibxuIUVHfpm9Rm7Mi6whpM5x3bs69bTVfReeIHluLZqqLTivlDW4rbOj3qe3PHYrsOsOn6T9K+aS037W5g7l0fZckdn+OKzVs4pDVNdWc7S3e3ctxjGzFOsK1XfPUC7q4OLgLEIi7RN7y5/761buUl55zA75Y9p980J6xQU3/KJUSnzQnGxWuDifWziR+ynMM3/JQz/zG80rGfeP4RfPeyoVV7ERGRQsaY/0fu4vl7h9FV2SJjzN3GmDcZY5Zmbo4bYxxjzEkEXZ9kyoT8r7V2Q2n3/OD8TFWXvHGZ7susE5w89yRLn6A+ECcycNWSTFKbjyWVVyW2K93OLbtuzZsvx9rw+MJKbeZf76Fl0/n0pOL47CEZPi2X8HNfJqtjLvWdnUzfl+lq2+C6/btEKZC5keA4cMQLg3GzjgjGhW38wpVzOf0VK3je5UcUXwWZJ+wH31QpnbXwLGqjwfcMpybK/C+cRu3xsw6ylIjI5FLJcRwgDHU4YVdlkUgDBuiJRvGAtFf6Sm1Jr0hSW59Et8SeXPUUj1zV0hgpHA9qkr3YaHDD2+su7Ontlb//Xw578qF+22hob+e4zTtZfN+dxHtmBCOt4dCTTyNWnRerDbR09XLeYc9h5xkrOXPe8VQfdST1Z5zRb50DaZk7j2jV0K8pvPvd7+b1r3/9QefLJBuUs3t3EZHJbhSxHIKktocJTnt/a4w5K1ynY4x5KfDdcL7rrLV/K9U+D4vNVF61GONgHJO9SZ2CwSu1ZbsfNVjfZpOnvVQKzymsGv5yfsap9haO457suGxSW945dt90eNNvzMFFwv1IDzO5PtLcjBMf3gNbIiIiE4lvTLbKWiq89uzQ/xw67RZ2QlflQW3XtuzvuaS2gS8W53c/6odx/33Hv2tE+y0iImNvyN2PSun46f6V2mLRwguzlt6+i5XUw5EtnJa/Tzh8ks/zhulx0v7QL0AXs/vpf5NoOIUd91wOQFXbIUSNYfETlwHQkXoLh+3wuPbUl5LZknFM9uJ0VczlrAtOwd61nd5fL4KX5dZ94pIWLj/mBZz77D3UJHuy47M38xesYZlfx8bEAWqPuggiaTj2FdlEg+F6/alLRrSciMhUZ4xZCHwg/NUHPmSM+dAgi/yXtfa/8n4/IRwAEsaYDqAeyL9K+0PgnSXa5WHJJFI5eeE7EokAHtZAtZOmJ1m+kuUmcvBKbRvdHTT6NQDUbd3MdZ0PQDz3lLafX/HMOmA8jHX4VcMt/H7a3/jClov4CA4XuqcTSwdxNWlhn9/In72TWFI7/AvobmNj8LOpCY59ORz5Yojknoh/9NPnEI84RNyBn8M4flELsxuqeNdZhwx7+yIiUlylx3Ege33bcTNJbfUkTZw7m4/i3OjNeGOQPNWT7n9j3e1z0zo/yS1G4cNunh8peNjcyetD9Hldrczb9SwLdjzD0l17ufaUMwFo3r+fs2+4EYA57V3cz+zctvNvBuQfbpFM8brnzOfAXzfjxEd2bj2QpqYmmpqaDjpftptv5bSJiAzJaGO5tTZtjHkBcDOwGLjJGNNN8FxT5pLu/cClpd73IQu7H3UySW0mF1fTZLofHaBSm5+p1BZck851P5rAOoXnny12F28xV/XfOODlVTrPVHGbu2snq5rWszJ237AOZ968S/mPhUdx5Z8eZX5zzaDz3vqBM9i8r4vLfnD3oPOJiIhMFkGX4oE0maS2/te8G3q72BPNXT+O2D6nswP02NUYb8xuYGu6MTveC68JRIfaa4iIiJSdKrWNAz/T/WjeuNqaqj7zlDapzaaKn8ADOD3NdFHDJrOcLxzVMORKba+549qi4+O9haXWbd+LzuHFhHd86g0FozvDzID5c4OS7saBI+u29lkWHv/sudT2yc43c4/Jvr7q8EX87JilzK+phuNeDW4kW+1l2pvedPADExGRUnD6vJ51kCG/7+tdwDuAnwOPAQeAJoKHrR8HfgCcaq293A702PUYy1R3MXmnzPndj3bFW8tWqS1qYiydtmrA6cfwAAC3Rdez0wRV1Px0D55NE6k6OTtfQbgOf/lzm089f6O9ah+3TP8ajxPhDo7D+pmkNsPnYu9hD80cMmt43ZcDNF96KbM//WmaLrkkGJGX0AZQG48MmtAG0Fgd5V8fPYtVC5uHvX0RERlQRcdxyMU914QXy51cvt3ehkbSY5DUlkj3Py/PT2q74KF/knLzq7MVJrX5vovNm+6FF91fcc13+WRbcO4c8Xw+8NPvZudxwvXXnryWuldfxhOx3D4Yx8kmsM2pzSW79T+Jh4Z1C5j/hdMwkfG5jJSp1OZGdRlLRGSIRhPLAbDWbgaOAT4DPEIQPlPAvcD7gZOsta1jdgQHY214jd3HOC5+upeIF8S9RFsaYyJYW/xhs2yltn7dj6bwTK7pvmDfTaffvy5AsdvefjhyRmI3n7r1GBY88JaDHsLX78tdqz50xac5efl0bnjP6VRFXa644gre9a7iVWMWTqvhOStmHHT9IiIik0VB96N+YVLb8c+sZ8aBVk5+8mHOf/jOguX6xuRMpba+Z7VufvGTvHNeG14TiJazGxARERkWVWobB9ZP96vUduTcr3Hflpdkf+/e31bSbfo9A98rmL75AtoP/wMAScfws2lHDmmd1eniXaRWJXIJease+BqpEy8jVtO/Sy4Ti+HkVWjb3OTwB5PgrafNC2ZY/lxiT97EJ5fNpevTnwaCyjjxiItN5rbd8trXQvPDsPMhMIb6iMtZ0xr6be/wx9cP6bhERGT0wovfIzoTtNb2AP8dDhNStnvOvHFuJAKksA50xtvZd2ArcNyY78vyhuNJNPTvue1n9mL++u/Lee7qH2fH3c8TQAyTCuKoMbkksswtdYOhfctJNC25A+s7zApvwM8Jq8tYa3Hc4HXSwrdftZZ7NzRw6UkLeeYjue03Nx88ycxEIjS/7JLhHK6IiJRBpcdxIHt0bpgkZvIuYO9qah52t1+DSaXa2PDEp+lxL+83rTGvUvqC1t08NWNu9vd+ldq8KORVV9syI9jnaDpJJLxkH/UK9zs9r45ZX/w8LS+8iO5kGvvL12anGWOyj9tdcugl1N3eA1s3jvAox1ZNY4w1L1jKISfMHO9dERGZFEYTy/uspwP4VDhMOL4JHjZzjIuX7iESXmdO9jJopTbyux/1ct2PHnLiybQ/lIu/C3iWXaaBIEc/V40t3+rVqzn1rq/yf341cA4uKRw/hpsKrk+3e4anUg0cV9Xeb9mH9uauw5s+N9Pnz58/tEYQERGZ5HpTHkmbS0hL2SDBPJPUVtfbzcX3/yM7f10yRWcsmreGMK6T17WogXjnbaSqDsOP9EkEzztt9sIKrREltYmITFhKahsHftriYwqqu9RWLWfz+nVwRPB7osQPH/uJvifw+Re6DenwrdAbMeykFoCITZE2USJemrQbIZpOkYpEOZjqvKS25raNVD38SVjzvwB8yHbz8cxWo1Fe8ak17NnSAcB1734ObT3J3An8pf8HwFuNYf0dfweKPjCOicdhyemw/k/Qsuyg+yciIjJa2XBkcye7mUptmVE9yc4x3Yen77sn+7qjflfBtE/bD5NMVlHX00uEXGK7F4vh9HbjpIOn1XfWP130y+DOf7+a7Q9fiGMjnJV6loZdvZzW3cNngU4s6d7g4nxdyzmsmnksx80KDnr2pz9N4okn+NiHP9TvgryIiMhE4mduSpv+3Wl2x2OkvdJVarv1ti8Bf2RvzWzgnIJpL0qeyJfy9yuvOkwDwc1va2HnzuW0tZ4M5M63bRhrm7p6SIfdnts+VU/f8sYPUDVtGgDRYtVPw2aocqupi9XTM/zDKwtjDKvPXzzeuyEiIhOItZmuyiwYh4YZi4hseQIAz4lgjB1C96NOQfejZ7zmDWz44wYgyfPt7wFIOXVkktoygbOwartLk/tv6hM1wDnM6tgNrIDwhnxb2tBli9+GWf+Zc9n01KtIp/cMeJwLF7yent5ni0578XHziBepolp/9tl03HDDgOsUERGZSDoTacir1LbNNawE3LDXLrdPJfVIn4fQ8qfmKrUZGvZ/h1RsCW2zPwPksv1PXz6dnqhh1q+/y2PHn87GukZqDtJbiIiIjB8ltY0D63tYnGxgBcAY2netyCW1uf0vrI9qm72FJ/CxeO5StbGGnV3xfkXmv86bcXcv469bT+Wa457Dom7Dk/0LoPUz50VH8PTDud8brvgwXeHvd5g0OA74PiYapamlhqZZNQDMbqxidmNe16dFboZnmqzxRS+i/ffBhQXjOnDCFXDYBdAwt98yIiIiJReGKCfvlDmSid1hd9ppr3QVXvra/sTj/P6LQRVTokm6qnMJdBfZ37Ccjdz78POzFeXyObY2+9pknnrz4mTu3T/o7AU7nYeaH+CeBdfxti2tnJHXs/hTEY+zX3sKC458mEi0uiB5TVXXRERk0shUanP6x0rfgFfC7kcfe2w7hxwR4cs9awrGH7s/SazPZZk1mx5lzqyNtLCf8/kjADbhcvGLr8Eah//3hc9n5z2qZQUPdiY4dstu6hctBODIiy7mNptLk4vGc+fYUdfhTc+9iPWP30lva9Dd6qpzL2TDnbexbPWJ7Lv6ZyU7ZhERkTFnLTas1GaMw6KjDmHjpqCKuee6GMMQuh81+F6u+1HHdbHRKJBkDjsA8J267PPhR/Egt7MO25vXHbgXXHdfue8xXnztj3nejFqmX34k+3a1QwpSNpcEF0v6JGNhRZhII9UxlyMO//Sgh3nIIR8dcNpXLllZdPy8r30VSlh1VkREZCwZyMZ0gK7wmnYdQVEU2+d+cd8kt1xFFNu/39E861rqMcCHDp/PyoYaupZ+hJ5IjPVJn+aoUiZERCYqfUKPA9/3gu5H8yOrE3T7ceLTT3D30hUknNL8abr+vYvYwvp+ldpaWrblfrEOf31sGpxYuOyh972O7u1HM7f2nzz3sbt5VfsRvHZtLvOtZXefBULVq18KDz8GwPK//43o3Ll0ffg2AC48di5LXvc72q/5A05dXdHlB3PM/EYA5vzn55jx7nex85OfovlVrwoS4JTQJiIiZeJnirvkh/IwqS1zkp32BujmpAQS3V3Z16ahlSS5qixRUnQcmEZ3V/HuPx3TjBM7gra6FAZD095VuF6cu2Mpvk0XRzpbOYXpOLh4buENgAuOnsNrT1nM0sUtY3NgIiIiZZIJ4RG3fzVy3xhSJUxON8ADHMcemrLjjmrbxvfvCZ4am9Pjs6PaYYk3k03J3byR7xUs76Z8qqurC8ZddNFFvP6wZfx8217O+NqXqTnmaN5ywolU1dXzNv8rRFNJjn/8EczJhxcsN2fOxSRap9F0dlAFbvqCRbz9B78CoK0xON820YNXaBcREZkIfHJJbU2zarM3udNOBMdx8P1k0eVstmsyg82r1AZkH/hywuowxq3NJrVdwf9wyu77+fqD7+S5saDLbj9T9Q3Lsi1PEFtwOlUrWoi31MJDQVJbbbQO2M/MPQn2LlvBtGmns2jhFaVtjDzGcYIHy0VERCYBz1p8J1cMJkVwnX06ewHoilUVzJ+p1Pb5B4ICLh/+5U/4zuuez4yONnY1FF63drw2AM5saWBOPMaOM1Zmp9U2NVMLnFbqAxIRkZJSUts4SKeSQVJbXqU244CD4fQN63lw8YKSJLXZlE/r/z2BUx+l+aLlBdPcvJvU9+29kc3Lq/suTtPeY9nheTTtP4aVnW20RQpvzi9w23C2rGfr/DMK151X8jw6N0g0c2oi+EmPq16xCoCqD31wRMc0syH44mKMITprFgv+99sjWo+IiMhoZCK4k/eUWLZSWzjKG8Onoh0n91R4TU2cJPHs77u2HMLDz/a/Gd3gV3PA6cFYl1jtuXQ03091Kk00XQ/AzTU9gEOs3oG9kHTDqq4f2wmfmw3ANy89bsyOSUREpKwyVVeLVEn3HIdEuoRJbcYnSmGieI2f2+4v7uiiO2J4gMJttiYNzTGLKdIV6sqVKwH40LK5QHDeXdPQmJ3+y4++hpZOMG+9rM++GJYceQZLjuy/n3P+83O0X/MHqo45ZjiHJyIiMj7C8GjwMTg4riESJrX5bgTHieD7Say1BRXGIazUZkxQqc23OG5ueipcsUsagIhbRyaMR0nTnO7EI3f9O1OpbVn9flae83zWXvxyAGKxoPvvpbOfy6L6xezc+h0iC07llJN/XeKGEBERmdw83+IbgwnPiVNhpbaTuIO/8ELmtO8rmN8N76/P7wnmn7d7J0c9vqVgnkwHJq7Xyn1rj2BWXA9viYhMVnpcZxz4voePQ8GptAkqtWEgalMlSWpL7w9uRtuUj9+n+9HGxt3Z1/sbU3hu/+39pa2XJxI+rldNdc8cdnUVrsM6EebsuLPfcm60/9tqzkfXMO/Kk0d0HADNr3wF9eedO+LlRURESilzazk/Qd3NVGoLw6A/lkltbthtKC4z62aTyEtqozeC5wUn6Rf86c84rdB6/9l4qZ5wn4NlE93LqQsvsudrnbeP25b8hvvm3RiMiFbDuo/CRUokFxGRypGprBqN9D8XtsahN1W6iquO4xGjsFJMNK+7lDoPZiYsvSa4Y/7Q745h4x8W8Y2n4kR2QtPPc/t40kknsXx54UNrxXzi1S5z/vM/MUWObyCR5mamve61/W78i4iITEg2qKLuYMEESW2uFySi9ToGx8QAW7QLUuv72XjXt1Jb2maS2oJz+kiksLcRH0OXzd0Ynz07eAjMNZazLn8zNY1NADQ0HMPq1b/jvOP+m+po+ED5wrWjP24REZEKk/Ys1nGCmA4kbXCdfSlP8VN7MXPaWwvmP+fpZwFY0B3E6kQsd95r8l699sjXAjC3Koar81wRkUlLldrGgZ8Kk9ryboRjgkptGENTupXdpnHgFQxRel8vAG5DDL83jR+eiK9btwzP/0l2vqTrY03/t0LKGvJjfKTPvfnk9l3Ud21j3T/ewS2nX8Wbr2vDmV2Ne27/LwYmMrr8ydmf/OSolhcRERkL+REvm9QWjs12ZzIW2zVBXL1gwRvpdR/irzw/Oy0WXsQHcD2P2R+L8fApJ9Lb8jDEG7JZd2m/muk1jST3dbHzkBrYEyS99aQcnp59e+EG131ozI5FRERkXGQrtRVJanNcehMlrNTm+BgKq63lJ7VlRMIYnWp38ZM1JI4wzPxMjPghh2TnOffcgz/s9d7j38vxs46naYYqromISCWz4fl30P2oMQY3PA9PRSI4bvDwl+8ncZxY4ZK+nz2v9n2LU9D9aCapLUhwj0f7Xqc3dNncg2Vr1qyByJdhy7/67WFjw7EAzJh+Fps2fZ0Z05878sMVERGpUGnf4jsuTngfu9fmKptXf/pQzOkO1uQePFuxbx9/fc8V1Jz7ZcChJy+pjbx77+9b/T7et/p9Y77/IiIytlSpbRz4firofpT87kdNdszc3q1siSwa9XbS+4Kb025DHK89QToSbM9xuwtndCNA/y5XCm/VB94VredFyTSX3nIAP+z6zAkvFsw44POe1x5b0P2oiIhIJfLDrG8nL5Y7Thj/wh+myM3qkm3fD07iayIN3NQynfvMCdlp0bykNmMtFnAiczGEXXiHMd8jV131lact5seXnwjAge7cftdH68fsGERERMZTJtq5RR7wwnXpTXtB12Ql4BiPRBiHc9vvf759eupIanftwEkGD6h1Vxkin/wsC3909bC297qjXscxSmgTEZEKZ/MqtWW6H61OBlXZktHqsFJbkNTWf1mbPYe3XmH3o5lb5pmktli0oWDZHsh2P7o0PjdYzwlXwMXfG3Bf6+uP5Kwzn6Kh4egRHauIiEgl83wf38kVg0naXFxu3rUZxyusupokzTUXPZ87IhsASBTpWnTsrsyLiEi5qVLbOEin/SCpLT+iZrofBZoTrbQ1NAVn5qMoh5qp1GYiDl5rAtMQhW6IuFFSefF/b2+yaKW2Yl2OvKyuAfbv5rpdaYzfvzuW+pYqutoTI95nERGRSSEMkQUVTcMuQX3jAD6ON3aV2vx0LnHNcQpP6iN58dlYizUuxkRx3DnAvmz3o5uiHmfEXXoAx7ecuKQFgBceuo6fb/s9V515FWvmrBmzYxARERlPmWvkbrTIxW/jYjyPRNqnKlrsAbDhMY7Pl8zHCsalnP7n4LXEibXuIRPl0x2HMecNFxGJ69KNiIhIP+G1dWOCqmvGMVQneoim03RV1ZO0QTKbb4sntRFWZ/N9W3AdPBXeUHfCpLba+HTyr4IfsPBfLz2WFx7xPNwSfE8QERGZ6tK+xTdOtlJb0uaKpxgs0XQCL9OVN9CT3AfVDk+4OzgtfTi9Rc7rRUSkcqik1jhI+2ksTmH3I44JxhiD63l4uNj06JLDvNYgqc0mPbz2BH59cJKd6R4N4Mk/L2RrewxM4Qn4+f/uAuDvy35aMD5a5TJzpsPizddy+IbctPlbb2betn8E61elNhERqXCZwi1O3lNjbiS44ezjYIzF8fonf4/a7vWw7V68vGps1D9RMIvr55Lpnp5l8bM3zYOdNtZlzrnzeSrqs3jtLADmHdpMVdRl0+fP5yPPPZOHX/Mw6xasozpSjYiISGUKYngkkjsX/o+Ozwcv3AhxL0UiVZoEdcfp/51gfzxeZE7wbW7elbH3UaeENhERkQHYfpXafJuiKZGgq6qORHhObotVasvrftRL+dkq5gDp8Hw/EqaytVTPLVi2ZfqLeMnx84lWx3AiSmoTEREZrbRn8R0n2ytK2hbGV8cvPDdP2PD+d6Z6zNzZ2WnZq/WjKBojIiITi7KPxoFNp/Ax2TKqEMRWE94Yd9I+1jikU72j2o7fE9zwtikfP+HhBxXXcdxc8O/cVovnWmqijQXLHv9UkFD3xIx/c/Oyn+FMDy64u66DAZZu/gvx5IHs/Ge+9wzO/a9LAYhkLgLo+4KIiFQom+l+NK/sqpvpugQHx/Ew6fbSb/hbJ9H5rXPY9fSTAPhOku7avQWzLH/i8ezrA7UNPHr46wqmG+vwzdueAmDBsmbe9u0zqWsOuybVyb6IiEwRmbx0J6/CynR7AGN9rOMS81P0pkuToO6Y/slxqzo7i87rhzfQX/bpL/KLN55Uku2LiIhUJD/z6JbFGAfHMRA9jJpkit5YVbaLUM/v/+C4tbnqbOmUTzSWl9RGYaW2abXzgs35Drfd+mqSzrFjd0wiIiJTUKZSmwkrtaVsYfpC36S2ZCxW8HvDay4D4I1vfCMzOtqYv383p218cAz3WEREykmP/I6DtO8Fz4/ZYpXawITXzRPJLqI1TSPejt+dSWrzSPcm+Vn79QC4fZ4S9xzLtOpZ7ACe+0A3HXXbgGnBRGPZMPNuXu6/hV17EziuoVhP5FVHHEF09uyCcfXhDXIREZFKkzmNzk8Bc8ML4plKbXaM8sN+8NQJpJ78BQCJ+i2kKCyv3tLRSufsmQDcd/gJHNp6NJD35Jp1sk81NFarNLuIiExVQaCO5lUyx4ng4mEdl7iXojdVmqQ24+QuwH/JvpP5W49m8fpLsuNubdvJMTUuTbEZ2XHzDzuyJNsWERGpZNaY4AZ42P2odWfhWot1DF54Ul60Upv1MWH3o+mkV9CNqBeeOrthUltz1bTMUgDEXFVnExERKSXP9/Edh0h41T1tHd57y2eJuUl+zBcxfuF9aS9SmN6QDpPeZs+ejWt9nv/wP8uz4yIiUhaq1DYObDrT/WiOUxvFOAbXiZB5iLs3OboKL5lKbX7KpzeZeyLNcVIF86Vdi+sGldiWb0/y0ifvBmB+7EFe78zh+2d/n2PPWgBA06wa8Ps/ZW7yvkDUtVRR1xxn3aWHjmr/RUREJqxMdZe8YJ65rO3jYBwPg4O1/RPBRyuVV379q8ta+B/zruzv3/zGp1n+VK5S2/bmA3lL5rofzXwLqa/S8w0iIjI1ZSJ0fvejxrg4+PiuS8xL0zvK7kcfeeRdPPnkF3FMLjnOJc3yxy4hmvfk+axNf+HvO37GN1tvHdX2REREphRrsQTdjzq4OE5Q38W14BsnW6nNL9r9qM12P5pKekUrtbl43NZVj+sE1WAyhc1jUSW1iYiIlFLQ/aib7X40ZR3ak43s6Qke/Opbqa2vZ599NpjPUdqDiEgl0p3MceB5Xv/uRx2DrQJ6DG4qSEZLJA8MsIaDSzxzAL8rSF7z2hOkvCQEeWs4eZXaemNVdNVMg/CCumthKc/yw5ptvKHuC0SWfRJnzokwBw5ZPQuAzlRhUhwUJrVFYy6v+fwpI953ERGRic6GSWEFCep5ldoc4+MbG1wod8euS8/fzViUfX3JPX8DY4gmc92XOzb/q14mqc3hRSvn8sZXHR10zyIiIjIFZSqqRuJ53ZY4kWxSW9zrHnWltl27/wyA7xyWHRchjenzfGG88xlSTbWc8uLT2fCDO0e1TRERkanEGjDYoFKba/AsQaU245AOL70XTWrL637US/lEYrlEtcyVbxeP7f40br31Npy8PLZoREltIiIipeT5Ft/JdT/q2cJYe9jjj3PX2pOKLrvJ2cVTTz015vsoIiLjR0lt48APux81fbrxdGIuXo+PCWuc96a6R7yNPf8T9hXuGEhb0nlPhluCE/lnbp7Dj1/yNtobmjkyFXZN6kPM9bgx1sIpyS9zz5qX91u3LZbUFlX3ZSIiMnVkboS7ebE8k7vm41DnGQ4Yi+/ZgovfpbS47qiC32sTvXTW1fHzC2o5MGMTS/YsIWJz8dkzuUptTdVRJbSJiMiUlq3UZnIJZsaJ4uBhjUOshN2PutHcOXSmKzOAb876Jcc8uI1UQ/D7msPmsaEkWxQREal81gbx3GBxjIPjGDyCh7YLk9oSRRb2MU6mUpuPm1epzQu/JTh41PhN3HXXPaw9Obdo1FUVGBERkVJK+RbfGJwiSW2bGmaz5JlnWPzMMwD8/kUXkYzHs9P/FnukvDsrIiJlpzOwcWB9L+h+tE+PZPHqKjxjcbwgaPcmu0a9reicWgDS5Eqzbn38Zn7HS7m+7gLaG5qD+dwaABzfErfBRfY9NINbmPdo02m89iIV5JTUJiIiU4jNdj+aSwxz8yu1OT4WS2tH/yfCS2F6fB5rZlxQMM61HoevX88tyxOccPIJvO2Db8P1c/G50wm+eGxyLctWzRiT/RIREZk0wrgdieXOeZ1IXqU2P0VveuTdj1qbW7auZXf2tUs6+7rT7aa281H2NATn7dF41Yi3JyIiMuVYG1Zq8yFMavPDSm2+cdjTHcTitNf/GnvQ/ajBWouX9IjmVWoLnzfHxSMWqcHaPhVW1f2oiIhISXm+H1RqC8+j/bzY+5FT3kTVG96U/T2/F7TB1Dpjc11eRETKT0lt48DzfHycfpXamhtaSOMR84IT40R65JXaMiJNQbZ6Onwa/LzzzqNq+mP81rycf5x4Xna+tDsNgFjaMiOylW+8YhXffOVx/da39R3vZMfHPtZvfH73oyIiIpUuE8GNyd2wzhQ+s5igapvx+emdm8dk+67pH3fPve6v1Hd0AtAUbwJraOhtAWDmSTPpcoJ9vbPKY8XcxjHZLxERkckiW3U170Eu48aCpDbHHXWltnS6I7etvK7II3lJbRaozdtEtKqK4y94IYee/JwRb1dERGQq8QEDmEz3o1hc32IdhyTBdfFUqrXfctb6GGPw0xZrIZJXqS0d3ix38Vi/dyM286UhvBIQj+o6uIiISCmlvSAh3TGZSm25uNwer6fqOeuyv59+yz8GXdeFpx3LRVzPWxduHJN9FRGR8tMZ2DiwfhqLwemTTR6NRfGMTyQdnCgnvZ5Rb8ttDp70TodfBGbPbuLJIl2LP2KPAODp5ruZ7W7gBcfOLbq+zptvLjo+U65dRERkKrAEsTo/+jnkKrW5YaW2luqxqWTaEp9Lq+kE6rPj6rpyT5+7j0/jlr88zRG7TwGgfvV0zNM23D9orFGFVRERmdoysTwSya/UFsVNefiOGXVSWyrVln2dzrv04rXNyr6O2gg2ZSAW/h6Ps+6yN4x4myIiIlNK0PcoJjgLxxjCSm3gG0O3H2MaAyW1WXAcUskg1kfyqq91hjlsMZL4NpKX1BY45ZDpY3VEIiIiU5KX9vAdJ9v9qO8X3nOO5CWUN7e1Dbqu48+8CKq3wrGvKPVuiojIOFEm0jjw0x4+BtNnfDQW3GCOpIM/S2+6d8TbMFEHtyFGw9mLSJHm+tgDzJixiSefOn/Q5Q5U7R50uoiIiORuhJuC7keDnz4ODhaMJWbG5qvWMS3P4RfTtheMq7/mh1z+ruBC/P4b4ux+qjM77c0/vTf7+v3nHDYm+yQiIjKpmCDZuyCpLZap1OYQ91IkUiPvfjSdbs++9sglk++//yW0RzYBYVKbl/uuEInHR7w9ERGRKcdaLITn307QnajJJbUlPA/XrSue1BZ2P+qFsT5Tqa090c7DTg+1XpIW9vHR1Z/Idj+aTgdZ6A1VekhMRESklFJe2P0omUpthV19R2LDiL3GwMnvgFoloYuIVAoltY0HP401Ln16HyUaD06ME9GgulrCG0V/3xGHqiOn4cRcdkUPANAybetBF7PG5565rxr5dkVERKaAbJdleRnqrsmv1BYE+WR65DfDB/NYg8MPjj++YFxvQ5zOGkNVqrboMv9ILePx9AyOXbFoTPZJRERkMslWXc2rOh6NVQdJbS7EvCT7u0d+Tp5O55LL8yu1OYBvuoPt2QikchfrHafwwr2IiIgMzjcGsDjhA2U9GBzfwzMOnT0dRKPNpJLFkto8jMmv1BYs/9a/vZVHTQ/zU20YYEb1XMBgb53Ogw+cW6ajEhERmVr8dCrofjRMarN9ysJEDtL197Jly3jnO985ZvsnIiLjS0lt4yDtpQH6dT8aC5PauuJBUltvOjHyjXg+xg3+vNOefwhA9qmywSzzd3HCG785rE3N+tjHhr9/IiIik1juRnjuBDsTZX0cHGOxxpJIpku40dz3hv2xvvVeoTsd3CB/0cPvKbp4h63iX+nFRF3dMBcREclcIzd5SW2RaA0OPp4LcS/FF657fMSr97xcUtttnJ59fVx6KV5eUpub0mUZERGREQlPkR0sJjwjNxEHvBTWGH7zyH8TidST9jr6L2otxjGkk5lKbcF58kN7HqIjGqXR6wLA94IvDNXXu/T0NI71EYmIiExJ6bSP7xgcfKzv8PM3nMSv37Q2O32wSm0LFy7kRS96ES0tLeXYVRERGQeDpzbLmPDTwRNgpk+ptlh1kMxmwqIuifTInwq3aRucxAOx2UHFFmv73wDv672Je4a9rZZXq7KbiIhMLZmQ6hR0P9q3UpslNYpuy/rxUrlt5X2FOHfX33jzyufTnWrH8V0aEzMGXY1vB50sIiIyJWRiuclL9nbdoFKbdSDmjy6G51dq+6O5GIDTnniAZruMbbHdkIQDbie9qMtRERGRkbA2iOcGizFBPHccg2MtvjGs2FJP5ITagpicW9biOA7pVFipLZb7PtAZjVLXGyxz770PAuB6HifefRe3n/GCsT4sERGRKSed8oLuR60P1nDyssKuQweq1HbllVeWYe9ERGS8KaltHKTCi+Omz03lusa64EU6uLqe9FOMhPUt+BYTCdaTSgXrGUpSW72zZ1jbWvKHPwx/B0VERCa9IKa6eUltsbBqW4oYjuODgXQpk9rSvVgLBgcvL6THe9OkU3t4+9/fzjE7z+i32IYFUejoyf7uW2W1iYiIAMEF87xuTSJuDS4evgNVNojhKc8n6g6/mlra638DPRZWbd8y8z5+0LiNR8yDzJu9EICLPviJERyBiIjIFGYtlkxSWxCrHccQsUG3pFVJBzdSQzK5r9+ifjqNcdxcpbaw+1GLoSsSod7rwsewceNTQJDUNm/rVuqPXFeWQxMREZlKvvv3DfgnTMOxPhTrdSxSmM4wbdo0rK5xi4hMGernYhz4tniltvrGBiBXfSXhjbDLMi+8gR5Wakunw/UM0P3oV67/Ny0dHhds3Igpkvdmk0m2f/gjJJ95pt+0qkNXjGwfRUREJjE/U6ktryfPadEIUS/FXmaE3Y9S2kptPa3s7K3HNRF+sSiWHW0SDjdvuzl43WeRupY4j1Xn9mHt0mksm1FXun0SERGZpLKVXfK6Es9UavMcQyx8KKw76Y1o/V6RqjCzbVBNtSfu8M+GB3jhXblp8VrFZxERkeHKVWoLux91wPUtvnGoSURx3Vo8r7vfcr1dHVTV1pFOFlZq2zfvG1hjqOcA+fUAXM/DN4ZVC5vG/JhERESmmpa4CbofNT7FUhdMn6S2d7zjHbzzne8s096JiMh4U1LbOPDDpDOnTxZ5fVOQ1BbxgpPpbWylre3fw16/TQfrNa5Da2srv/zlL4MJ6f4X412/i9a2pbzt2nb+Y/tHuW7aZf3m6b7vftqvuYanzjm3YPyym24a9r6JiIhUglz3o7mvUo4xzO1oZRezcJwgFqfTJUxq69jJ/kQ1jnG5a3ruRN4kXK579rpgeyZIZL/gbcewYs0sXviuVezvynVn/os3nkQsoq9/IiIihDfB85/sikZqwqQ2S0M0CkDPCJPa0ulOjInxwE3vpCqVAODtW1sA6I4F20wfOCK3gJ4yFxERGR5LWKnNxynoftTBGkNNIoLj1OClu/ot2nPgAFX19blKbbGwUpvbBMCMxvtxyPWi4vg+1hrOPGzW2B6TiIjIFGTSaXzj4OAVLdBinHBcJMLyf/yjzHsnIiLjTXc1x0Emqa2v6ppqAOKp4OZzJ3U8vuHjw19/T3BD20QMd91+GwA1NW3MWRiUS8+/VF4fCZ4GX3X0Hk5Nfo1HVryt3/pskYpxjS+5mNj8ecPeNxERkUoScQpro83s7qCVFqKOE3Q/WoKkNt/zsL5Pz65NHEjF6ahvKZje7XbSEe0AIOoHFdzmHdrM8153JDXTqmjtTvZbp4iIyFSX6a4MJ3dZJOLW4uDhO5aWul4AupMjq6Ce9jow1OIlGkm5EV7U1k7UQip6Pd9MbsX4EIv0ZueP19SO6nhERESmHGuxxmAgV6nNNTiA7zjUJOPgVJH2iiS1dXZQXddAOpWp1FZ4m2QmOwt+j6TTxA16SExERGQM+KkkvuPgmjT48ez4Fxw7N3gRPozmVFcTnTVzPHZRRETGUeTgs0ipeTa4wW36PIhtjGFlegn3sQmATuoxJjrs9e//1YbghW/Zt3ULAIcddlt2+m+unw9h0bVET3DifuuuVjy/juccMqP/Cv3CG/LT3vhGpr/trcPeLxERkUqRqdTmRgqT2qrSaZJUEXHAOobUCKu75PvqK1/Isc87j8dvvZFEYjFtiwpj9d1NtxEJ77e/ZMklbH22l0g0uNC+60CvCr+IiIgUk+2urG+lth48x7AzGZxLj7T70XS6E0MNiajFc1wWmziQ4pppvwUizNlXhQkD+LlvfQ8zFi0Z7RGJiIhMOZlKbYZcpTY3PAeu8arwiOB5XVjrZxPfAHo7OvpUanNJeLnKbDPZnX393O2bcX0fW6QXFBERERk9m0hhjSHipDBeTXb8N16xim+8YhV+Tw8AtSefPF67KCIi40hJbeMgHdZKcyhyl9kJniarsZ10Uo9jhv8nSj5zAIC/PXAbG/fsBcCEGXRf5sMkFjyRnTeTWLehx4ILqxY291tf2//9tuD36Nw5OPF4v/lERESmikxSW99KbdWeR5IYUQMY8FKp/gsPQzpc/sEbr8uO66qpL5jH2FwltmnRGeyMbc/eoN/W1jOq7YuIiFQqS1DZJb/70Yhbg8Me0gYibgMAvamR3cD20p3gVdNRFZzTz/PTQJomvwNoxs/7CjH30MNHdhAiIiJTmQ3OzYMk9SBhzXEdnPD5bBOtIZkwgCWdPkA02gRA5/59pFNJapuaSSczldpc9iQ6Abik9WGqmnqprb00mL/9ANOA6AsuKOfRiYiITBmZSm1RJ4mT7l/F3KmuZum11xKdN3cc9k5ERMab6mWPA+uHmWRFctoyN6Hr6KCDeoxxh73+qsODbsnu3/N4wfg0LveZE3j0yEv7LbPHCZLUipVQ77j++j47qbeNiIhMcZmkNrcwJlZ7HgniZAq4ealeRiPZ091vXKz5EADOttdy6t6bcbz9ALx7+Qd58KZnieTF8h3tuaS2vgl4IiIiU1nmJnh+96N18RZcPHxjcCONwCgqtXmdpNNxWhuDh86mdXi4Zjcd4XeHiJeLy1W1dSM9DBERkSnL+hbfGBz87DX0WJVL1A8Sym3jbDrbgqqoicQuADpb9/O/b3kNAC1z57P7mQ6iVS7RmMPu3uD8e663m2Q6Quv+tQAs6XicWEOKJZ/8eFmPT0REZKqwqWRQqc1N4vrFz4/jS5eo4IqIyBSl7KRx4BM8Llas8U14Qb063UMP1TCCpDYcgzOzumCUBbro/0Ugcxl9N1XD346IiMgUla3UFi2M09WWIKktDPJ+cnRJbaneXFJaZ00d3VU10DCfKi/Na/g+S7bdhQGWNy2n4dbDAOjtylWH294WbP/P7ziVf37kzFHti4iISEUxALagUltDfDoxkqSdCKlwfFciPexV9/buoK3tHjq6eugKL7q3tPpEzA6enrWWWfsM77wmWP/SpulU1zeM+nBERESmGt+3eMYQIZ2t1BatimDSsWCGeB17N+0DIJEIuhNt27Uju/y0eQvYtqGVZStn4LgO+5LB+XeN007Ci3LXXXcBEOlN4UQskerCqukiIiJSIplKbW4K1+/fo5iIiExt6n50HPheUKLN2P6l2oxrIA1eq0NqRgzHiQ1r3clnO+h9dB/pedHsuHnzHqO2tp2tLOg3/1kPBk+gtZr+5VwBbJF9dBt0Ai8iIlObDW90R6OFX6WqgSRxjBtcDB9tUluyJ5fU9j+XfTj7+pDubVAN66uCbsZ3d+0m2du/ksz2th6aaqIcNa9xVPshIiJSaSzg2MKktmikhhgJUk4E3wTnwu09w+9K/M5/nQlYUqkI3bHgAbKmPRFi5gn+vttw8cOx7ENuxy0/YpRHIiIiMjXZlI9nHCKkcfIqtfV0BQnlXiRKZ3uaZiCRDCq19XZ0ZJevbpxG94H1NM6qodfz+fa2oPvRaqeNVDp3bd12WqINI6vcKiIiIoPzfYtNJwAweMT8xeO7QyIiMuGoUts48MJKbYb+3YA5bnAC7qY80l4NXrpzWOve/c0HAOiN5k60ly67F4AOCpPRjt6c4NjNSY6quY4UEQ6f0//pcJt3Mx1g9mc+Tf055wxrn0RERCpOeKM7GosWjK5xDJ6JkI4HF8ptKjGqzST7xOGMC9t/Tyod4ZnqXTT2zODiOz5C267+XZVu2d/NvKbqImsQERGZ2jIJ6iYvqc1xqqiil5QTxYaxfv2OA8Net+8nAUin43THq4j5HrUeRN078OueIkWcdNgNaay6ZrSHIiIiMiX5iTSeEyS1Rdwgnrbv6cEJn9He2tLCzg3bAUiGldo6W/dnl+9sDeJ14/RqvvXsbu44ECwYj+4hlQ7W5zsRUh0RYvXDr9wqIiIiB5f0fCIEMdnBJ25mj/MeiYjIRKOktnHgEZwEO7ZIUlvYX1nE80gSI+0NL6ktIxFeRA+ePw/8oOu47OsX77yR0x/poSXyDLNqr2P9Z87lunedVrCOA3+9nuQzzxSMa77kkmwXqSIiIlOVNWCsTyQaLxhfFcbI3qqgQpvxiyelDVUy7H50Vn3hU+FL4+vZn4jQ3D2bczZcQdzL3RBfdNQ0bnxsF2/6yb/ZsLODQ2epwqqIiEgxhsLK5MY4xGySlImCE5yv/+jOZ0ikR1adJZn26YpVMTusgL4/2o5xe0mm5pByHbCWma973egOQkREZIryepJhpbYUjhtURk0nPea0BtfetzY1Ed3nkU642e5H9297FoBLPvV5DuwNztur66O058X6WM0mmuOLcBwH9u8Ga/hjywXlPDQREZEpI0hqCyqkG2uJRaeN8x6JiMhEo+5Hx4ENK7VRJKnN1EWgC6KeT4eNkU539JtnKHpSwUl5JBIkt23jArbXvQiAd/TezlsevZpfdB3PcY2/x3veZ6iOuQXLp1tb2fbud+M0Bt2VTXvzm2i88MIR7YuIiEilyXY/WlVVML4mrLrSE0vgWEPE9q+eNhyJriC5/bnTHsqOe+m//071kQfYnLK87MGPFMx/zBnzWfPCpay48vrsuENnK6lNRESkL984uPRPVqsiTdJEMY7BseAb6OhNE69zi6ylP2tziXJPJg/lqUXzWdPZDlhan/s+eOI7VKUcnprVjOP7uLW1pTokERGRKcVLJElnKrU5wYNeie40c7s9qlIpeiNBZfV0t8vWbT+hoWEVWx55kAVHHsOCI47mm2/+OwCx6giRdO46fQ1dJFP7iMSraUq1AbBo5YnlPTgREZEpIpHycZ3gXrb1XKKx+EGWEBGRqUYlt8aBZzLdj/Zv/tp5zQDEcUmYGOlhdj+a3caCGAA2luaXXMoHzeXZaWu37uPa1uAm+LTIM8yc3tJv+fTOnQD47e0A1KxaRXzZshHti4iISMUxQXWXaKwwqa3FDS6Et8ajxG2EmOnF922xNQzJnk0bcfBpieeS46Z5e6mq6mZPKvc9Ysmx0znj1Ydx2stWQKTw+8XaZXq6TUREpK+UiRK1/bsSi5s0KSeGMT7RMIZ3JYbe5VgqFXRrlk6ezE3NZwBQ09ODE01wb9UK5uyz1PvBQ2i+qqCLiIiMWLI7gTUOUVJEI0FS2+mvPBSAmlSa7miQ1Gb94Dz9sUc+yr6tW5ixaAk27zw9VhUh/9HzanrYuHEFDbMWcvQTTwFw8glHluGIREREpp6k50MkiMTxdIpoPDbOeyQiIhONrqCOAz9ManNs/+Y/+sijiNsIjjEkiOL7Pfh+akjr9TqCTPbIklpuvvX3REwXfznmJP5kXlww3/p7T6PdmwtAU2Qb05v7J7Wlduws+D1+2OFD2gcREZGpwBpw8IlVVxeMP8QGMf7ZyGxqjEMMj9buZLFVHNzGm9hy44+ZVt3DYzXHAvCCrj9y2om/AuBAItfl6PzDmjnilLkk0z6b93UB8JHzDuMzLzySo+c1jmz7IiIiFSxFhEiRpLaqsHqbF6/ivWtnA9A5xKQ2a326uzcBcOOu40g5wRPm71pfh9sQ48Y/fZyP/SJOzIZdqyipTUREZMS6e8KeSkjjuMG5+SGrZ3HIsY3UJn06Yy5+JEqmiGqyJ4jnK046lURPLrZHq1z2J3qyv9c+fTadndM4sHkPs58NktXdRp1Xi4iIjIVEyiNdHSSiN6Q7aJoxY5z3SEREJhp1PzoOwofDcOjffUn9zAYabA2utSRNEMQ3PvmfHLriU4OuM7Wnm11fvheAmx79C+mW6Ry27CY2xy/NzlPd/ife+2gNsCo77gP2bXx19tHZ363n0X7NNez5729mxzkNDURnzRz2cYqIiFSqzDPd0erCLsMWRQ1RL8mzzkIWx1K0JnrZvP0A01YM82R88x20/vBSdvaewO9fcgVPTl8MQEtNLum8a9cR2deNM2v47b1bed9vHsyOO//oOSxoySW+iYiISE56gEptVY4PFtKxauamWgHoSvTvprSYZ575Nk89/WU8HH66MKjSNq/bZ36PJbJyFsf8upZ/L60DYGZXgvO//f0SHY2IiMjU09ubgsYoEVK4Tq6KesOcJuoSu9hXFcWPVwdPpQF+2uHYsy9g3qGH07Y7Vw3drXL55Y494FTxDftGUt5JAHiPPZ6bR0ltIiIiY6I76eGHD443pxLUzZo+znskIiITjZLaxoFvggvixvRvfqcmQpWNko64JNwq7rFrYOuPD5rU1vq7JwFI+ymebPEw1b28e95/Z6fHeh7grT1LcJ4NKrQtid9FQ3QTK17+WTDBiX3iySd55nWvw9uzt2Ddsz7ykZEfrIiISCUyBoMlVlWY1BarrWXhvm1snbGQmvhT0AXrb/gDx6+4Ylir7/neC/jdlpUY/GxCG0AVwZPot17/Ida0LwfgqOct4E03PMLjuwq7LFdCm4iIyMDSuEWT2hocDzzoqa4luXMn0EJnYmjV03fs/ANtNPEouQfHttUE1di+et1bWdARpTMs8vqcD3yEafMXjvo4REREpqqeRBKIEiGN6+aqqNdPq6JhEzzbUEWqOk6yI0rNjF6MMay56KUA9HblYvvGRBLfqeJi76dMc/axvSdY19rtuYfG3KamshyTiIjIVNOd9HBjwXXsxmQC06BEchERKaS+LsaBdYIkMtf0r9RmXIcYUXY0NgHwYy6noWHl4OtL+/idSZ5x9nAL9wEWM7+1cKb26dTfVp/99avV03lP3YU874hZ+N3d9Dz8ME8//8J+CW01a0+i/ox1wzxCERGRymYNGCxVfSq1uS0tLNm5hWdZSFW0Fz8SYddt1wxpnb7ncf23v8593/4w39q4lrZUNQuXF1aGWcAW7r3xHcwME9oAbuzpLEhoW7Wwif966bEjPzgREZESMsbUG2OuNMY8bIzpNMa0G2PuMca8zxgTG6/9Splo0e5HZ8eCce21DXRuegaAjt6Ddz9qrUd395NcxXv5lnl3wbRnH/osM/dU01kddEdaVVvHglNPH+URiIiIjL2JGscBkqkgPkdJ4+RVaqtrqWJWB3RW1bBjcR1tx7wagBnzVlE/Laj+0tsRJLVZ4AubtoH1ObT7IUyylg1tVXi+Zd7evUw/6gBLLmjHqdFDYyIiMjlN5FgO0JVM40SDOF6T9DExxVwRESlU8ZXajDH1wPuAi4ElgAc8AfwSuMpamyz3PvlO0GlZpEilNoBYJMYJm9bz52NPodZAonfHoOtr+9NTJPZ08Y/4Yzw5u4V9ixq5t/752el1qQN86pF/ccA/E4A9boqNzGXDx8/F6+zkmVdfRmL9+oJ1zvzwh6hZtYrqY3VTXERExs9EjOMQXPg21hKtrisYH5k+nSVbnuWmY04nWWXBcUjVNw2+Lmt59tGH2b7hMR6++UbaGlo4Z94r+PpJy/nSjHh2vlPtLTTvaaW1Z3F2XK+x/OLh7cxoiHPRyrl8+LzDccPkeRERkfFmjFkE3AIsDkd1A3FgdThcaow5y1rbWnQFYyhFlFiRpLalDdOhB9rq6+nt3IhbY/jTgzt44cp5g66vte1uLPC4OTI77iv3tNGc9OnZt5/U4tkAnHToMRz/wY/iuP0fchMREZlIJnIcB+hNBnHcJY3r5pLa6purmH7AB+Cfyy9iCfezsmkN2NxDY+17ekhE4ISPHsd/bNjMos5fcWTdU7QfmA4Yjn/qAQBqVh9J1ZvVXbiIiExOEz2WA/QkPbxoFVGbIJ52s72LiYiIZFR0UttEDdY2k9TmRItOX9A4l/lt/+KobU/z6NzF9CR343kJXDd3Y7tj3166kik2/uA2nu1p5cnqffx55Sq2NOQutC9IPkDXnh9z5+Nbua3zCg4A7rQfcvl7v83b4xHctlbarrmmX0Lb8ltuJjp7dukPXEREZBgmahwHsGH3o5F4YaW2yPTpHPJ0UNVlZ/1M2NGDV12Pn+rNPnGW4fseXfv38/TPP8VNd2wB4G+nXMD9R6/le/nrtCn+h8uJdUf460OvYHlvA7dXpXg64rErEnyn+MbLV7F22bSxO2AREZFhMsZEgD8RxPEdwGXW2puMMQ7wUuC7wCrgp8AF5d6/lIlSa3v6jV/UsITmnft4dnojvT1tnHvUbG7fuBdrLWaAi+s9nUkeuuc73Bs5AYAle7Yzr20Pp+1fwu5HfsZjzbmq6Sd85OPEqvXkuYiITGwTPY4D9CaDZ9xcP01+oZm6ljjNu4JKbDuapnHtAzdy9NFxIj2P0t5+H3V1K/no09u49+IW2LAZbJp319wAQEND0IvJnCe2A1Bz6oXQtKCMRyUiIlIakyGWA3Ql0iRro9TSjZMa98JxIiIyAVVsUttEDtbGDbsfjRRv/kWHL+eo27ZzXzKBNQ6/sK/m8B9diHvaVcw55FC2/Oxu7rjnb2xoSuAZw6Z5s7npsPML1vHhx/9I7OE19EZez0+TcwB4NrKPjo0LOP2U1XQBe8J5a9aexPyvfpUDN9xA04tehIkWT7YTEREpl4kcxwGSJkrUpnGihSfablMTxz2ziXrbwR1N81id3kp3TR1XX/FCXv3dPxKNROGJ60hVTeevP/ghG57YyuKm1Vxz0QvZPGMaKbfwu8FJ9nbe0vkz9tzzNtr3Lme5DXqOvzeeJmlg6YxafnbFGuY0Vpft2EVERIboNcDR4euLrbV3AlhrfeBXYUz/OXB+mKT+t3LuXJooEb+z3/jGuqUcz438o+m5EDGcPKOWvzy0g/U7OjhibkN2vlTS4+7fPADcSe+cr/J45HC+w4do7O7gqw/6OLYZg+Gf9a0k/Vric2fzkrd/SAltIiIyWUzoOA7QnQ4Lt6dNQeJ5rCpCE4ZjdnTw0Jx6ZiSP547dv+X0erjv3tdz27Vf5d4LmrLzv85+n5nOAQB2bD8EgNquLuasacWsfk3ZjkdERKTEJnwsB+hOpOlpNlTTTV2nHtoWEZH+KjapjQkcrP0wqa22rqHo9FlnLqHtxrtYuG8Hdy85nGvNC3lw0Wpef+1TxJL38JfZKRae2MOD9UfxeN2K7HINto1X8BNm/+EF+IlTsUA8TGibtesenvPEL4h4iX7bm/uFL+A2NdF8ySWlP1gREZGRmbBxHKDNaaLBO4BxnILxxnVpWHksKw88wi2Na2la0sysZ+9hR9NyvvSut5FubOLJpaexLbqFDadfQfqMwq9iLXYv7+WLxEmQIM7stgRP3vA5AG6pSjHD81l93mKeOH8FIiIiE1zmLvDNmTjexy+BzxF0L34ZUNZYngoT1Puqqp7PCdzNTe55PH30SSy95zbikXm89Sf38Ju3nMyvrv4u7Z0dbJqziH8sWES9s4jncR4/MlfgWI+PPfQU873gPPyGbT8i6fdiHZfTX3AJs5cdUs5DFBERGY0JHccBOtJBd6JO/3BOdUOcC+9P8sgsy8a5Z9C2axPNVft4MHoaf81LaANYa24HYOPtL2bVn2/j+AO/on5+D43ffhyqil+/FxERmQQmfCwHaN2ziWQj1NhuFqSWjccuiIjIBFfpSW0wAYN1azzoeuSQ2dOLTo9EXezsaczu2MSL7vsHvz/udLY58/jMMQBzAbiTVdn5F/hbmNXq84KnnsBpPRV7wGPlQ58jmupk29zTmLX739R27wIgtmwZ87/xdXofeQQ/kaD+zDOJTC++HyIiIuNowsZxgDbTSKPfUXRaw4UX8qobvsb+l9RyzdJjYOm8ovPle5H9NSt4nKWJTdTFD2THP/2vK0mtbuaZOpjpWT5/8dE0VKmiqoiITGzGmBrglPDX64rNY621xpi/Am8Bzi7XvgHs69xNighR3+s3LR6byWE8RqNt5VfHr+b+PZs4r+1enpk+i+fdnWTn0c8BwFgfaxw6qOdHXAHAqze0cdSzu7ih43q60x30kKDhlR/m5WevobFa8VtERCaHiR7HM56pjgMwvUjl1drGOO27e3jNo3v54dEz2N78IR7Mmz7fbmERm5jNDkxXlAc3ns2JNz9Ew4F2Zq1qp/nTP8JUN5XnQEREREpsssTyna3dRDb/iG3HXM6Snq3MPOyw8dgNERGZ4CoyqW2iBuub/vIjOjc9y5MLZwJw3LIFA857+bvO5ntf72DG1i6auv/C349aRWdtnDnONg5r28uG+CJWHdhE464GZq5vZMXjf+BA/UJiyWeYt/02XD8FwOqzZlG79nPUrj0JjMlWlIkvU7a7iIhMTBM1jqd7e/nin//Brl2P88wRp7M2/e+i8zVccD5HXnUVn//1f/C+Sz7DRnMYi+1TbDbLqLUdnG//yK3mTN7BV0i31TPvvjjr7TLa06/g6Xk1PGPrWTW9hWOPn80pn2qkqlY3wUVEZNI5HMiUM31kkPky02YbY1qstfvHcqd2bn6Ge+95nHv33k3bYRcS7dnebx5jHE5Y+QM+/MAnuMq+hydmLOGJGUv6zfc8/wZe+EyMn8+tYVvvIk699Xpmb3+af8yPsvaENZzw0nfRVBcfy8MREREZKxMyjgM8cetDbG1bz2Otu7ltxSyqbDdLW+b0m+95lx/JzT9dT/X6/bzDOcB/H1FPc9cBjm97iJpULwt378JLVrHANtD79FrO3nEryy45garnvANz+HnguGN9KCIiImNpQsbynW37+PVf/oLxd7AllaCpeRe/POaVHDCNXLhxA3XvPHMsNy8iIpNURSa1MQGDtbWWz0XirD/y+QBM9/Yyr3nlgPO7UYc3vf+lPPnYAzz8vU5W/fkx0lHDwhrLtBNXMOuwo7nnTy6LpvnUrtjCnP/3TbzWNoxjiC68ql93aCIiIpPIhIvjAD/49fe5asEpMG0WAKt27i46nxOLsfi3/8ecDU/w432P09l+Nfjd7K9fwrEnvJ5tG87j0sZ20rVf5piTD8c5uY0LZk7HccxY7r6IiEg5zc17vW2Q+fKnzQXGNJZ/4u5r+NOM02H6hQCs2ZcoOl9Lyym8YNXnab7vKjZuP4IttpnV25+lLtpB3CaYXltHY/NZuLMdfnr00dg9e4if+3nc6uqx3H0REZFymZBx3E8leUXiWbbVHwr1hwJwgfcHTj7uff3mrWuOc+E7VuL7Prt/cg2vveUJktueYafdSdushRxNO81r5sPc5+BW+VQd8jlQZTYREakcEzKW/+A33+Mby88BjikYf/q2fbzlDa/G6Pq4iIgUUalJbRMuWBtjOHXnUyyv3o5N13HZktVDWm75EStZ/pWVRaedc1Th0+KR5ubR7qaIiMhEMOHiOMAFp19I681fYKezmEO7urniDR8fcN5IczORk9awhDXkelINNM3t88TZ7BljsLciIiLjqj7vdfcg8+VPqx9wrhJZ1tnD6dG7iflpTtzVwdvf+sEB553WvIaLzloztBXPn1+iPRQREZkQShbHjTFvBN4IsHDhwlHtlHVcTmq9n32RraSJs7B7Dx9+7qXU1vSvqJrhOA6zX/Pi7O8DzykiIlJRShLLSxnHAU6cfwjveOIX7K+ezj7bwNzEftZFGzjr0itwY6p0LiIixVVqUtuEDNaffc3HRr0OERGRKWBCxvF5ixbyodd+a9TrERERkaEpdSz/8OUfHvU6REREZOistd8BvgOwevVqO5p1ua7LNy8Z+OEyERERKa1SxnGA5573Yp7Liw8+o4iISB71UTkIa+13rLWrrbWrZ8xQFRUREZHJRHFcRERk3HTkva4ZZL78aR19JyqWi4iIjIuSxHEREREZN4rlIiJSMSo1qU3BWkREZPJSHBcREZnctue9njfIfPnTtg84l4iIiJST4riIiMjkplguIiIVo1KT2hSsRUREJi/FcRERkcltPeCHr48aZL7MtJ3W2v1ju0siIiIyRIrjIiIik5tiuYiIVIxKTWpTsBYREZm8FMdFREQmMWttN3BH+Ou5xeYxxhjgnPDXG8qxXyIiInJwiuMiIiKTm2K5iIhUkopMalOwFhERmbwUx0VERCrCj8KfZxhj1hSZ/lJgafj6x+XZJRERERkixXEREZHJTbFcREQqQkUmtYUUrEVERCYvxXEREZHJ7UfAw4ABfmuMOQvAGOMYY14KfDec7zpr7d/GaR9FRESkOMVxERGRyU2xXEREKkKlJ7UpWIuIiExOiuMiIiKTmLU2DbwA2AzMA24yxnQBXcCvgQbgfuDS8dpHERERKU5xXEREZHJTLBcRkUpRsUltCtYiIiKTl+K4iIjI5Get3QwcA3wGeASwQAq4F3g/cJK1tnXcdlBEREQGpDguIiIyuSmWi4hIJTDW2vHehzFljKknCMwvBpYAPvAE8AvgKmttcojr2QM8U4Jdmg7sLcF65ODU1uWjti4ftXX5lKqtF1lrZ5RgPVOS4viUprYuH7V1+aity6eUba1YPgEolk9KauvyUVuXj9q6fHROXmEUyycltXX5qK3LR21dPorlFURxfFJSW5eP2rp81NblM2Gur1d8UttEY4z5t7V29Xjvx1Sgti4ftXX5qK3LR20txeh9UT5q6/JRW5eP2rp81NYyEL03ykdtXT5q6/JRW5eP2loGovdG+aity0dtXT5q6/JRW0sxel+Uj9q6fNTW5aO2Lp+J1NYV2/2oiIiIiIiIiIiIiIiIiIiIiIiITD5KahMREREREREREREREREREREREZEJQ0lt5fed8d6BKURtXT5q6/JRW5eP2lqK0fuifNTW5aO2Lh+1dfmorWUgem+Uj9q6fNTW5aO2Lh+1tQxE743yUVuXj9q6fNTW5aO2lmL0vigftXX5qK3LR21dPhOmrY21drz3QURERERERERERERERERERERERARQpTYRERERERERERERERERERERERGZQJTUJiIiIiIiIiIiIiIiIiIiIiIiIhOGktr6MMbUG2OuNMY8bIzpNMa0G2PuMca8zxgTG+W6ZxljvmyM2WCM6THG7DfG3GaMucIYY4aw/DJjzP8aYzYZY3qNMXuMMdcbYy4ezX6Np7Fob2PMPGPMW40xvzHGPBm2dU/Ybr8wxpx5kOWvNMbYIQzLR3bU42OM2rokbWWMOc4Y81NjzFZjTMIYs8MY8/uD/a0mqlK3tTFm8RDbOTP8sMg6rh7ispHStMLYMsbUGGPOM8Z83BjzO2PMM3nHcGWJtqHP7ElqLD7v8tat90WeMYotiuNFjFFbK44XUeq2Norj/RjFcTmIsfjMy1u33ht5xii+KJYXMUZtrVheRKnb2iiW92MUy2UQY/F5l7duvS/yjFFsURwvYozaWnF8AKVub6NY3o9RLJdBjMVnXt669b7IM0bxRbG8iDFqa8XyIkrd1kZxvB8z1eK4tVZDOACLgE2ADYcuoDfv9/uA5hGu+3hgb966OoBU3u9/BWKDLH9+uD+Z+dsBL+/3HwBmvNtwvNsbWAD4eevIrLe7z7jvA+4A67gynCcJ7BxkWDzebTje7+1StBVwRZ//hbY+f8Mrx7v9xrutw/f1YO27M2y3zDbeWmQdV4fTeg6ynqL/FxNtANb1+Z/OH0b9nkGf2ZN2GKvPO70vytPWKI6X9X1dirZCcXyo72vF8cLjWdfnf1pxXEN++yuWT+K2RrG8rO/rUrQViuVDfV8rlhcez7o+/9OK5Royba84PonbGsXxsr6vS9FWVFgcH+P3tmJ54fGs6/N/rViuIdP2iuWTuK1RLC/r+7oUbUWFxfIxfF8rjhcez7o+/9MVHcfHvcEnygBEgIfCRtwOPDcc7wAvAw6E0/4ygnU3AjvC5dcDq8PxMeBt4QedBb41wPJLgM5wntuBFeH4OuDTeX/8D453O453ewOLw+VuAi4D5uat9wjgmrz2+uwA67gynH7LeLfTRG7rUrQVsBZIh+v4PTA/HD8N+Hbe3+qS8W7H8W7rIWz7qnDd3UBTkelXh9OvHu92KtHxrgP2h//r/w94ed7n7JWjXLc+syfpMMafd3pflKGtURwv9/t6VG2F4ngpt604rjiuwSqWV0Jbo1he7vf1qNoKxfJSbluxXLF8yg9j/Hmn90UZ2hrF8XK/r0fVVlRYHB/r9h7CthXLFcun/DDGn3l6X5ShrVEsL/f7elRtRYXF8rFs6yFsW3G8guP4uDf4RBmA1+c14Noi01+RN/2sYa77s3n/REuKTP9IOD2d+aP2mf6TcPqOAf4J/zec3s4Is+Mrpb3Df7LjBplugOvC9XYAVUXmGVUAmmjDGL+3R9VWwG3h8g8B0SLT/xpO38QkyIwey7Y+yHarwsBlgZ8MMM/VVFaw7vd+ADZTmmCtz+xJOiiWT/62VhwvX1uXoq0Ux0u2XcVxqziuIdu+iuWTvK0Vy8vX1qVoK8Xykm1XsdwqlmtQHK+EtlYcL19bl6KtKi2Oj3V7H2S7iuVWsVyDYnkltLViefnauhRtVWmxXHG8rG09peK4g2S8Jvx5s7X2ziLTf0nwgQFBZvNwZOb/pbV2U5HpVxFkK7rApfkTjDG1QKZf2f+x1rYVWf7z4c8G4KJh7tt4GZP2tta2W2vvG2S6JShnCEE26OFDXfckNpbv7REzxiwFTg1//S9rbarIbJn39mLgOeXYr1Ear7Z+MdAcvv5eCdc7YVlrvTFcvT6zJy/F8vJRHC8fxfHyURwvE8VxGYRiefkolpePYnn5KJaXiWK5DEBxvHwUx8tHcby8FMvLRLFcBqBYXj6K5eWjWF4+iuNlMtXiuJLaAGNMDXBK+Ot1xeYJP+T/Gv569jDWfSiw8CDr7iTIxC227lOB6oMsv5mg9N+w9m28jGV7D1Fv3mu3xOueUCZAWw/meXmv/zrAPLcTPCkAE/y9Pc5t/frw50Zr7T9KuN4pR5/Zk5dieflMgNiiOJ5Hcbw0FMcrgz6vJzfF8vKZAPFFsTyPYnlpKJZXBn1eT16K4+UzAWKL4ngexfHSUSyvDPrMnrwUy8tnAsQXxfI8iuWloTheGSbq57WS2gKHk2uLRwaZLzNttjGmZYjrPqrI8oOt+4hRLn/kEPdrPI1lew/FuvBnEnhikPmONMY8YozpNsZ0GmM2GGO+a4xZVcJ9GWvlauuRtFXmvb3bWru72AxhlvHjmW2MYL/KaVze12Em/xnhr98fwiJnGWOeMMb0GmMOGGMeNsZ8zRhzyGj3pULoM3vyUiwvH8Xx8lEcLx/F8cqgz+vJTbG8fBTLy0exvHwUyyuDPq8nL8Xx8lEcLx/F8fJSLK8M+syevBTLy0exvHwUy8tHcbwyTMjPayW1Bebmvd42yHz50+YOONfo1t1gjKkrsnyrtbZnCMsPdb/G01i296CMMUuAN4e//spae2CQ2acTfAD3AHFgBXAFcK8x5j9KsT9lUK62HklbZbYz2H7lT5/o7+3xel9fDhiCfqt/NIT55wNLCfrBriEILu8CHjHGvKUE+zPZ6TN78lIsLx/F8fJRHC8fxfHKoM/ryU2xvHwUy8tHsbx8FMsrgz6vJy/F8fJRHC8fxfHyUiyvDPrMnrwUy8tHsbx8FMvLR3G8MkzIz2sltQXq8153DzJf/rT6Aecq7brri0wfbPmh7td4Gsv2HpAxphr4DcEH1F7gwwPMuhH4IHAoUGWtnQbUAucA9xJ8MH7MGPO+0e5TGYx1W4+mrSrtvV3297UxxgVeG/76F2vtzkFmvw94O0G/63FrbQtBX9UXA08BMeBbxpiLB1zD1KDP7MlLsbx8FMfLR3G8fBTHK4M+ryc3xfLyUSwvH8Xy8lEsrwz6vJ68FMfLR3G8fBTHy0uxvDLoM3vyUiwvH8Xy8lEsLx/F8cowIT+vI0OZSWSyM8ZEgJ8DxwMp4FJr7fZi81prf1ZkXBK4wRhzK3ArcAJwpTHme9ba9rHb84lNbTXuzgXmha+/N9iM1tpvFBnXDfzOGPMP4B5gCfBlY8zvwn7NRUQmBMXxsaG2GneK4yIyZSiWjw211bhTLBeRKUFxfGyorSYExXIRmRIUy8eG2mrcKY5PEarUFujIe10zyHz50zoGnKu06+4oMn2w5Ye6X+NpLNu7nzBL92fARQSlJ19prb1hJOuy1vYCHw1/rQPOGul+lUlZ2zrfENqq0t7b49HWV4Q/twHXjXQl1tp9wH+Gvy4CBuvjvdLpM3vyUiwvH8Xx8lEcLx/F8cqgz+vJTbG8fBTLy0exvHwUyyuDPq8nL8Xx8lEcLx/F8fJSLK8M+syevBTLy0exvHwUy8tHcbwyTMjPayW1BfIzkecNOFfhtKLZyyVY9wFrbWeR5ZvDsqAHW36o+zWexrK9C4SB+qfAJYAHvMpa+38jWVeeO/NeLx3lusZa2dp6AIO1VWY7g+1X/vSJ/t4ua1sbY2YBzw9/vdpa6410XaHJ9L4eS/rMnrwUy8tHcbx8FMfLR3G8MujzenJTLC8fxfLyUSwvH8XyyqDP68lLcbx8FMfLR3G8vBTLK4M+sycvxfLyUSwvH8Xy8lEcrwwT8vNaSW2B9YAfvj5qkPky03Zaa/cPcd2PFFl+sHU/NsrlHx3ifo2nsWzvrLzM85eTC9S/Gu56JrmytPUIZd7bM40xM4rNEP4NDwt/nejv7XK39WUEXUhb4AejWI8U0mf25KVYXj6K4+WjOF4+iuOVQZ/Xk5tiefkolpePYnn5KJZXBn1eT16K4+WjOF4+iuPlpVheGfSZPXkplpePYnn5KJaXj+J4ZZiQn9dKaiPbX+4d4a/nFpvHGGOAc8Jfh1OS8wlgy0HWXQucNsC6bwd6DrL8IuDwEezbuBjj9s4s7xL0Df4ycoH6l8Pf26JOynu9qUTrHBPlaOuDGKytbsx7XXTfgFOA+vD1hH5vj0Nbvz78ebO19ulRrgsm0ft6jOkze5JSLC8fxfHyURwvH8XxiqHP60lMsbx8FMvLR7G8fBTLK4Y+rycpxfHyURwvH8Xx8lIsrxj6zJ6kFMvLR7G8fBTLy0dxvGJMzM9ra60GayF441uCDNI1RaZfEk63wFnDXPdnw+W6gMVFpn8wnJ4GVhSZ/pNw+nagscj0b4XTDwDN492WE6C9XeCX4bIp4GXDWNYcZHoc+Fe47k6gabzbcrzauhRtBdwWTn8AiBaZfm04fTPgjndbjldbF1nPqXnreUUJ/lYtwFPh+rYAzni35QjbZXN4DFeOcj36zJ6kwxjHFr0vytfWiuNlaOtStBWK4yPdjuJ48ePYjOL4lB/GOL7ovVG+tlYsL0Nbl6KtUCwf6XYUy4sfx2YUy6f0MMaxRe+L8rW14ngZ2roUbUWFxfGxbO8i61EsL34cm1Esn9LDGMcXvS/K19aK5WVo61K0FRUWy8fyfd1nPYrjxY9jMxUax8e9cSfKQFCe8KGwAbdm/pEIqtm9FGgPp11bZNkr8/5xiv1hG4Ed4fRHgePD8THgLUAinPatAfZtSfhhZ4FbgUPC8bXAJ8MPBgt8cLzbcbzbmyBQ/4JcoH7pMPfrdOAm4NXA/LzxUeAs4O68bU+K9h7Dth51WwEnhx94FvgtMC8c35L3gWaBS8a7HcezrYvMe3U43z4gPoT9ejXwO+BiYGbe+GrgImBD3raH/OV2vAegGZieN2wJj+H/9RlfN5y2Rp/Zk3YYy/9BvS/K09YojpezrRXHy9TWRea9GsVxUBzXULz9FcsneVujWF7OtlYsL1NbF5n3ahTLQbFcQ/+2Vxyf5G2N4ng521pxvIztXWTeq1EsB8VyDf3bXrF8krc1iuXlbGvF8jK1dZF5r0ZxHKZQHB/3xp5IA7CYoJxg5o/YRVAeL/P7fRTJFhzKPxlwPLA3b74DQDLv9+sH+6cDzg/3JzN/W96HnCXoK3jQLNOJNoxFewPPyZuWBHYeZHhZn+XX5S1vgW5gT5+/lQd8brzbbwK0dUnaCriC4ItVZpnWvA8zyyiziSuhrfvM15D3WfD1Ie7Ta/v8rToJPo/yP0N6gbeOd/sNs6039zmugYarh9vW6DN70g5j+T+o98XYtzWK4+Vs65K0FYrjB23rPvMpjueOa3Of41Ic15Bp/zH7P9R7Y+zbGsXycrZ1SdoKxfKDtnWf+RTLc8e1uc9xKZZrGNP/Qb0vxr6tURwvZ1uXpK2osDg+Vu3dZz7F8txxbe5zXIrlGsb0f1Dvi7FvaxTLy9nWJWkrKiyWj+VnSDif4njuuDb3Oa6KjeMOkmWt3QwcA3wGeISgQVPAvcD7gZOsta0jXPe9wJHAV4GNBFm6XQT9yr4BOM9amxhk+WvDffsuwRu0iuBD7UbgJdbay234Dpksxqi989/TUWDWQYbqPss/HG77twR9BvcATeHPB4H/BlZaaz82zP0aV2PU1iVpK2vt94A1BH27bwNqgN3ANQQZ3FcOc7/G1Vh+joReTtBGAN8b4jI3Ax8D/kxQPjVFkGV9ALgH+CJwuLX2W6PYr4qiz+zJS7G8fBTHy0dxvHwUxyuDPq8nN8Xy8lEsLx/F8vJRLK8M+ryevBTHy0dxvHwUx8tLsbwy6DN78lIsLx/F8vJRLC8fxfHKMNE+r80k+mwXERERERERERERERERERERERGRCqdKbSIiIiIiIiIiIiIiIiIiIiIiIjJhKKlNREREREREREREREREREREREREJgwltYmIiIiIiIiIiIiIiIiIiIiIiMiEoaQ2ERERERERERERERERERERERERmTCU1CYiIiIiIiIiIiIiIiIiIiIiIiIThpLaREREREREREREREREREREREREZMJQUpuIiIiIiIiIiIiIiIiIiIiIiIhMGEpqExERERERERERERERERERERERkQlDSW0iY8AYs84YY40xdrz3ZTiMMbeE+33leO+LyECMMTXGmPOMMR83xvzOGPNM5v+tXO9dY4xjjLnMGPMXY8w2Y0zCGLPbGPNvY8zXjDFHlGM/RGTsKJaLjA3FcREpF8VykbGhWC4i5aA4LjI2FMdFpFwUy0XGxlSM5ZFSrkyknEYZBF9nrb26VPsyERhjbgFOH+HiP7LWvrZ0ezM55H2wX22t3TyOuyLDcyJw7Xht3BgzH7gGOD4c5QPtwDRgRjh+M/DYOOyeyKSiWF5IsXz4FMsnJcVxkQqiWF5IsXz4FMsnJcVykQqhOF5IcXz4FMcnJcVxkQqiWF5IsXz4FMsnpSkXy5XUJpPZrgHG1wG1B5mnp/S7U6Ab2DDG2+hrP8WPNwY0h69bgWSRedrDn1sI9ntvyfduYvpU+PMWgg9XmTxagfvyhq8Cs8d6o8aYacCtwBLgAeDjwE3W2oQxJhKOvwB4Yqz3RaRCKJYXUiwfPsXyyUlxXKRyKJYXUiwfPsXyyUmxXKQyKI4XUhwfPsXxyUlxXKRyKJYXUiwfPsXyyWlKxXJj7aSq+ChyUGFG8acArLVmfPdm/Blj1gE3h7+eYa29Zdx2ZoLJe4JB7TKJGGNca63XZ9xmYBHwaWvtlWO47V8CLwPuAs601naP1bZEpjLF8kKK5QNTLJ98FMdFpgbF8kKK5QNTLJ98FMtFKp/ieCHF8YEpjk8+iuMiU4NieSHF8oEplk8+UzGWO+XYiIiISKn0DdQjYYw5yhjzHWPMRmNMtzGm0xjzkDHmc8aY6QMscxhBoAZ4k066RUREhk9xXEREZHJTLBcREZm8FMdFREQmt6kYy5XUJlOOMcaGwzpjzExjzFeMMU+E/7A2b74aY8wrjDE/NsY8YIzZY4xJGGO2G2OuMcacN8g21mW2U2Taa8Npm8PfjzfG/NoYsyNc/9PhPjX3W/EYM8bcEu7blUWmbQ6nvTZsmyuNMevDdttujPmJMWZJ3vzTjTFfDNu2xxiz0xjzPWPMrIPsQ70x5sPGmDuNMfvDNnnWGPNLY8zaQZZrNsZ8xhhznzHmgDEmGW7zIWPMt40xZ+XNe3Wfv83Nee+L7N+mz/odY8ylxphrjTG7wvXvMcbcEL5Pij7p0Kfd6o0xnzfGbAjbZG/4XlozyHFVG2PeH7ZHqzEmFW73MWPMj4wxFw/WntKfMeaDwIPAG4DlgAWiwNHAR4GHjDGriiz66vDnw9baB8uxryJSnGL5wBTLFcsrneK4SGVQLB+YYrlieaVTLBeZ/BTHB6Y4rjhe6RTHRSqDYvnAFMsVyyvdpIzl1loNGipqAK4k+OezA0y34XAFsDN83QMcyF8GeG3evD7QBnTljbPAfw2wjXUD7UPeejcDryTot9uG6/fy1v0IUFeC9liXt851B5n3lnC+K4tM2xxOexfwUF67deetfzuwGFgKPB2O6wISefM8ATQMsP2VwLN586Yzf5e8v8NHiiw3H3gmbz6PoN/0dN64W/Lm/3re396G8+7MG+7ps/4W4B99/vZtfX7/AxAbpN3eAzwevk4Q9M2ev7+XF1m2nqA/6vzjbwVSeeM2j/f/3EQY8tq533u3z3yvD+frIAjMs8PxLnA88Ldw+rN9///y3gM/BGoISjc/Fv4ftAK3A28r9j7QoEHD8AYUywfcFxTLM/MrllfQgOK4Bg0VN6BYPuC+oFiemV+xvIIGFMs1aKioAcXxAfcFxfHM/IrjFTSgOK5BQ8UNKJYPuC8olmfmVyyvoIEKj+Xj3sAaNJR6YOiBuiP84DwTcMJpK/LmeyHwJeAUoCZv/Bzgk+QC7AuKbGPdQPtALlB3Ab3Ad4EF4bSa8J89s+7PlKA9svtCaQJ1K7AJeB5BtUc3fL07nP4rgn6U7wdOCpeNApeQ+6LzH0XWPwfYFU7/bfjBGQ2nzQQ+kxegLuqz7PfC8ZuAswA3HO8S9B/9ZuALg7wXBmyXcB2ZdrkfeH7m/QDUApfl7fdXB2m3NoIvBC8FIuG0w/PWnQKO67Psx8Np+4AXA/FwvAPMJciI/s54/89NhIEhBGuCLz6t4XznDDBPBPh3OM+7+0zbEY7/PkGQzv9SmP8l+y6gZbzbRIOGyTygWD7gvgwWs8J5M3HlyiLTMp+ViuWK5RNqQHFcg4aKG1AsH3BfBotZ4byZuHJlkWmZz0vFcsXyCTWgWK5BQ0UNKI4PuC+Dxatw3kxMubLItMxnpeK44viEGlAc16Ch4gYUywfcl8FiVjhvJq5cWWRa5vNSsVyxfEINVHgsH/cG1qCh1ANDD9TtwPxRbOf94XpuKjJt3UD7QGFW+9UDrPvL4fSNJWiPdQwhIIXzZoLGlUWmZT4Mu4HlRaZfnredncC0IvN8Jpz+ZJFp3w+n/WyQ/XtPOM8DfcZnPjhfMcy2GUqgfnU4z3qgcYB5jifIDE8AMwdoNwucVWTZaoKMfAv8pc+0a8Px/TLuNQz4/uz33s2bJ/O/d99B1vW+cL7r+ozvzQvQHvAxwicpgAbgE3lB+4/j3SYaNEzmQbF84H1RLB/wvTBguyiWT/xBcVyDhsobFMsH3hfF8gHfCwO2i2L5xB8UyzVoqKxBcXzgfVEcH/C9MGC7KI5P/EFxXIOGyhsUywfeF8XyAd8LA7aLYvnEHyo9ljuITF0/sdZuHcXyfwl/rjXGuCNcx38MMP4P4c/lxpiaEa57rPzWWvtkkfHX573+jrV23yDzLDPG1GZGGmOqCMrLAnxxkG3/OPx5bJ/+xtvCn3MGWXakXh/+/B9rbXuxGay19wKPAjHgjAHWc4e19m9Flu0heMoB4FxjTGPe5Lbw51gc11R0Svjz8LAP+aIDwdMlEDy5kM/J+3mVtfZz1toDANbaA9bazwLfCue5cID+xkWktBTLR0axvA/F8klBcVykMimWj4xieR+K5ZOCYrlI5VEcHxnF8T4UxycFxXGRyqRYPjKK5X0olk8KkzaWR0q1IpFJ6I6DzRAGg7cCZwMrgEaCEpv5aoBmYO8wt79/gIAHQX/bGc0EGd8Txd0DjN+V9/qeIczTRFBiFYLs7arw9Q3GmKHsx6K89f0ZWAt8wRhzGPA74J+ZD9KRCr+AnRT+eqUx5qODzN6St1/F/H2QZTPTHOA44Obw9z8DrwDeboyZQVCu9nZr7XDfaxKYG/6sIvd+G0zfL8kd5P7OX6K4LwJvD1+fTVCGV0TGjmL5yCiWF6dYPrEpjotUJsXykVEsL06xfGJTLBepPIrjI6M4Xpzi+MSmOC5SmRTLR0axvDjF8olt0sZyJbXJVLZ7sInGmLUEJS2b8kZ3EgRNSxCwp4fjaxl+oO4YZFo673V0mOsda0X321qbzguwAx3bQMc1N+91flb5YPI/SL8EHEvQF/kbwsEaYx4F/gp8z1q7YYjrzdcCxMPXzSPYr3zbBlkmf9rMzAtr7c+NMScC7wBeHg4YY54EbgB+EGa+y9BkvmT/ylr78hEsv43gPXHAWlv072mt3WqM6SDol3ygL20iUjqK5SOjWD70/cqnWD6+FMdFKpNi+cgolg99v/Iplo8vxXKRyqM4PjKK40Pfr3yK4+NLcVykMimWj4xi+dD3K59i+fiatLFc3Y/KVOYNNMEYEwF+QRCkHwDOJ+gTuN5aO8taO5tcVjLAkNKlZUD5Gf3V1lozhOGWzALW2pS19mXASoK+yP9O8IXqKIL+3B81xrxvlPt13hD368oRbGdA1tp3A4cCHwWuIyizupzgqYh/G2O+VsrtVbid4c+RBtGHhjm/HeF2RGToFMsnDsXyASiWl4ziuEhlUiyfOBTLB6BYXjKK5SKVR3F84lAcH4DieMkojotUJsXyiUOxfACK5SUzaWO5ktpEiltL8A/tAc+31l5nre2bUT27/LtVsXbmvR5x1q619kFr7aestWcRfMl6LnArQcD9kjHm2GGuch+5jPnRZhPPG+K0fk9FWGuftNZ+3lp7PjCN4P15TTj5XcaYF4xy36aKTBnl440xI+l7/YbwZ4Mxpujf0xizgCD7HGDTCLYhIqWjWF5eiuU5iuVjQ3FcZOpRLC8vxfIcxfKxoVguMrUojpeX4niO4vjYUBwXmXoUy8tLsTxHsXxsTNpYrqQ2keIWhD/32AHKJxIEASmNe4Bk+PrCUqzQWpu21v4NuABIEDwh0PdvlskQLvr0gLU2Ra5f9NHu1xlDmOZzkL6lrbW+tfZfwEuALeHo541y36aK3xBk70eBr5hBOqQ3xjjGmKY+o68BWsPXHxhg0Q+FPy1BP+8iMn4Uy8tLsTygWD52FMdFph7F8vJSLA8olo8dxXKRqUVxvLwUxwOK42NHcVxk6lEsLy/F8oBi+diZtLFcSW0ixbWHP2cZY/r1W22MmQ+8s7y7VLmstV3Az8NfP2SMWTjY/MaYlj6/xwealyBIZ8rn+n2mHQh/Ng2y/HfCn+cbY84fzn71caoxZl2RZaqATLnX6621bXnTBjwua61H7stN3+OqeMaYZmPM9MxALp7V5I83xtRllgnb9t3hry8H/mKMWWOMccJ1OsaYw8Pyu48Cz8/fprX2APCJ8Nd3GGM+aoxpCJdtMMZ8HHhLOP1H1trHS37gIjIciuVlpFiuWD4ciuMiMkSK5WWkWK5YPhyK5SIyBIrjZaQ4rjg+HIrjIjJEiuVlpFiuWD4cUy2WK6lNpLjbgS6CrORfG2NWABhjXGPMOcAtlLAfYAGCfrC3A9OBO40xrzbGZMpTYoyZYYy52Bjze4I+3PM9Y4z5vDHmpPzgZoxZDvwMqCEIZtf3We6R8OelxpiaAfbrp8BNBO+F3xtjPm6MmZu3jVpjzBnGmG8CTw9yfO3Ab40xLzFBP/QYYw4D/gIcRvBl4pN9lrnLGPMNY8w6Y0xt3jbnGmOuIugvHODaQbZbqe4H9uQNmSdGPtBn/H/nL2St/RFBQE0C5wH/ArqNMXuBXuAx4L8I/ib9/settd8EvkIQPz8H7DfG7AP2A58Nx19H0I+7iIwvxfLyUyxXLB8qxXERGQrF8vJTLFcsHyrFchE5GMXx8lMcVxwfKsVxERkKxfLyUyxXLB+qqRXLrbUaNFTUAFwZ/pPZAabbcFh3kPW8OW9eC3QAPeHrPQQlNjPTFvdZdt1A+wC8Npy2eZBtLx5o3SNoj3UM/ZhvCee7ssi0zeG01w6y/KDbOdhxAYcDG/Lm8Qj66u7s87e4cYDtZpbZn/e3sgRB+t1FtveqvHmSwNbwOG/vM18D8Kc+22knKLHp541LDdJu7wEeD1/3EpT3zN+/NwyybGae1iJt8ZXx/p8bj6FP2ww2XD3Ie/FLwAPh3zIdvm/uAb5BUH7XGWT7ZwG/I/hymQT2EvQl/srBltOgQcPQBhTL+65rHUM/5ltQLN+MYvmEHlAc16Ch4gcUy/uuax1DP+ZbUCzfjGL5hB5QLNegoaIHFMf7rmsdQz/mW1Ac34zi+IQeUBzXoKHiBxTL+65rHUM/5ltQLN+MYvmEHphisTyCiBRlrf22MWYLQUbraiACbCPI9P0CEBvH3atI1tr1xphjgNcAFwMrgRaCD8MnCbKObwT+r8+iZxP0tX0qsBDIlMF9ErgN+Ka19t4i2/upCbqLfhNwNDCHIhUsbVBO80JjzHnhvq0Nt2EI3hOPATcDvx7k8FqBE4GPhMe2gCA43AF83lp7Z5FlXh4e23OAJcBsgvfhMwSZ09+x1v59kG1WLGvt4lEuv5mB+/seyvJ/A/42mn0QkbGnWF5+iuX9KJYXoTguIkOlWF5+iuX9KJYXoVguIkOhOF5+iuP9KI4XoTguIkOlWF5+iuX9KJYXMdViuQkz6UREZAwYYzYDi4DXWWuvHt+9ERERkeFSLBcREZncFMtFREQmL8VxERGRyU2xXEarX5aliIiIiIiIiIiIiIiIiIiIiIiIyHhRUpuIiIiIiIiIiIiIiIiIiIiIiIhMGEpqExERERERERERERERERERERERkQlDSW0iIiIiIiIiIiIiIiIiIiIiIiIyYRhr7Xjvg4iIiIiIiIiIiIiIiIiIiIiIiAigSm0iIiIiIiIiIiIiIiIiIiIiIiIygSipTURERERERERERERERERERERERCYMJbWJiIiIiIiIiIiIiIiIiIiIiIjIhKGkNhEREREREREREREREREREREREZkwlNQmIiIiIiIiIiIiIiIiIiIiIiIiE4aS2kRERERERERERERERERERERERGTC+P8hZ/Tjq9t5JQAAAABJRU5ErkJggg==\n", "text/plain": [ - "" + "
" ] }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/pimp/evaluator/local_parameter_importance.py:268: RuntimeWarning: invalid value encountered in double_scalars\n", - " overall_var_per_tree = {p : [t / sum_var_per_tree[idx] for idx, t in enumerate(trees)] for p, trees in\n", - "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/pimp/evaluator/local_parameter_importance.py:402: UserWarning: Attempted to set non-positive top ylim on a log-scaled axis.\n", - "Invalid limit will be ignored.\n", - " ax1.set_ylim([min_y * 0.95, max_y])\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute('style', 'box-sizing: content-box;');\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " var nentries = entries.length;\n", - " for (var i = 0; i < nentries; i++) {\n", - " var entry = entries[i];\n", - " var width, height;\n", - " if (entry.contentBoxSize) {\n", - " if (entry.contentBoxSize instanceof Array) {\n", - " // Chrome 84 implements new version of spec.\n", - " width = entry.contentBoxSize[0].inlineSize;\n", - " height = entry.contentBoxSize[0].blockSize;\n", - " } else {\n", - " // Firefox implements old version of spec.\n", - " width = entry.contentBoxSize.inlineSize;\n", - " height = entry.contentBoxSize.blockSize;\n", - " }\n", - " } else {\n", - " // Chrome <84 implements even older version of spec.\n", - " width = entry.contentRect.width;\n", - " height = entry.contentRect.height;\n", - " }\n", - "\n", - " // Keep the size of the canvas and rubber band canvas in sync with\n", - " // the canvas container.\n", - " if (entry.devicePixelContentBoxSize) {\n", - " // Chrome 84 implements new version of spec.\n", - " canvas.setAttribute(\n", - " 'width',\n", - " entry.devicePixelContentBoxSize[0].inlineSize\n", - " );\n", - " canvas.setAttribute(\n", - " 'height',\n", - " entry.devicePixelContentBoxSize[0].blockSize\n", - " );\n", - " } else {\n", - " canvas.setAttribute('width', width * fig.ratio);\n", - " canvas.setAttribute('height', height * fig.ratio);\n", - " }\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'width: ' + width + 'px; height: ' + height + 'px;'\n", - " );\n", - "\n", - " rubberband_canvas.setAttribute('width', width);\n", - " rubberband_canvas.setAttribute('height', height);\n", - "\n", - " // And update the size in Python. We ignore the initial 0/0 size\n", - " // that occurs as the element is placed into the DOM, which should\n", - " // otherwise not happen due to the minimum size styling.\n", - " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " rubberband_canvas.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " var cursor = msg['cursor'];\n", - " switch (cursor) {\n", - " case 0:\n", - " cursor = 'pointer';\n", - " break;\n", - " case 1:\n", - " cursor = 'default';\n", - " break;\n", - " case 2:\n", - " cursor = 'crosshair';\n", - " break;\n", - " case 3:\n", - " cursor = 'move';\n", - " break;\n", - " }\n", - " fig.rubberband_canvas.style.cursor = cursor;\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " evt.data.type = 'image/png';\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " evt.data\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", - "mpl.findpos = function (e) {\n", - " //this section is from http://www.quirksmode.org/js/events_properties.html\n", - " var targ;\n", - " if (!e) {\n", - " e = window.event;\n", - " }\n", - " if (e.target) {\n", - " targ = e.target;\n", - " } else if (e.srcElement) {\n", - " targ = e.srcElement;\n", - " }\n", - " if (targ.nodeType === 3) {\n", - " // defeat Safari bug\n", - " targ = targ.parentNode;\n", - " }\n", - "\n", - " // pageX,Y are the mouse positions relative to the document\n", - " var boundingRect = targ.getBoundingClientRect();\n", - " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n", - " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n", - "\n", - " return { x: x, y: y };\n", - "};\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * http://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " var canvas_pos = mpl.findpos(event);\n", - "\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " var x = canvas_pos.x * this.ratio;\n", - " var y = canvas_pos.y * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We want\n", - " * to control all of the cursor setting manually through the\n", - " * 'cursor' event from matplotlib */\n", - " event.preventDefault();\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.which === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.which;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.which !== 17) {\n", - " value += 'ctrl+';\n", - " }\n", - " if (event.altKey && event.which !== 18) {\n", - " value += 'alt+';\n", - " }\n", - " if (event.shiftKey && event.which !== 16) {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k';\n", - " value += event.which.toString();\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(msg['content']['data']);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " var manager = IPython.notebook.keyboard_manager;\n", - " if (!manager) {\n", - " manager = IPython.keyboard_manager;\n", - " }\n", - "\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] + "metadata": { + "needs_background": "light" }, - "metadata": {}, "output_type": "display_data" - }, + } + ], + "source": [ + "# Plot learning curves: Training: Each curve corresponds to a different seed for the agent\n", + "mdpp_analysis.plot_learning_curves(list_exp_data, save_fig)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ { "data": { - "text/html": [ - "" - ], + "image/png": "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\n", "text/plain": [ - "" + "
" ] }, - "metadata": {}, + "metadata": { + "needs_background": "light" + }, "output_type": "display_data" } ], + "source": [ + "# Plot learning curves: Evaluation: Each curve corresponds to a different seed for the agent\n", + "mdpp_analysis.plot_learning_curves(list_exp_data, save_fig, train=False)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": false + }, + "outputs": [], + "source": [ + "weights = {}\n", + "weights['reward_noise'] = [.2, .2, .2, .2, .2, .0, .0, .0]\n", + "weights['action_loss_weight'] = [.33, .33, .33, .0, .0, .0]\n", + "\n", + "# Plot radar(spider) plot: Training: across different meta-features\n", + "mdpp_analysis.plot_radar(list_exp_data, save_fig, weights=weights)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Plot radar(spider) plot: Evaluation: across different meta-features\n", + "mdpp_analysis.plot_radar(list_exp_data, save_fig, train=False)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "# Setup to analyse an MDP Playground experiment\n", "from mdp_playground.analysis import MDPP_Analysis\n", @@ -4385,7 +439,7 @@ " )\n", " cave.performance_table()\n", " cave.local_parameter_importance()\n", - "# cave.cave_fanova()" + " cave.cave_fanova()" ] }, { diff --git a/rudder_analysis.ipynb b/rudder_analysis.ipynb new file mode 100644 index 0000000..3ab934a --- /dev/null +++ b/rudder_analysis.ipynb @@ -0,0 +1,715 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

A step-by-step guide to applying RUDDER

\n", + "\n", + "--- by Michael Widrich (widi) ---\n", + "\n", + "In this tutorial I will show you how RUDDER can be applied step by step and how a reward redistribution model can be implemented using PyTorch.\n", + "You may use it as a quick-guide to apply RUDDER in your RL setting and to pre-assess if RUDDER might lead to improvements for your task beforehand.\n", + "This code should be runnable on common CPUs in reasonable time.\n", + "\n", + "Links to further RUDDER code, our [blog](https://www.jku.at/index.php?id=16426), and [paper](https://arxiv.org/abs/1806.07857) can be found at our [RUDDER repo](https://github.com/ml-jku/rudder)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

Overview: How to apply RUDDER:

\n", + "I suggest the following procedure to check if RUDDER can help with your RL problem and to apply RUDDER:\n", + "\n", + "1. Draw a set of samples from your environment.\n", + " - A sample is a sequence of observations, actions, and rewards.\n", + " - There should be variance in the returns (sum of rewards) of your samples.\n", + " - Samples do not need to be from the same policy, you may also include human demonstrations and such.\n", + "1. Train an LSTM on your samples (or whatever model-class you want to use for reward redistribution).\n", + " - This part is a supervised ML task.\n", + " - The main task to train on is to predict the return of each sample at the end of the sequence.\n", + " - As auxiliary task, we will train the model to predict the final return at every sequence position. This will allow us to use differences of predictions for contribution analysis and in some cases it also helps to push the reward further back in time. Down-weight the contribution of this task in comparison to the main task\n", + " - If your environment also includes intermediate rewards that are not at the sequence end, you can use auxiliary tasks as described in our paper to introduce gradients via these intermediate rewards to simplify learning.\n", + " - I suggest to try to keep the model as simple as possible, as this made reward redistribution and contribution analysis clearer in my experiments.\n", + " 1. Start with an LSTM without forget gate and without output gate, \n", + " where the cell input only receives forward connections and the gates only receive recurrent connections.\n", + " 1. Increase the model complexity until the model is able to predict the main task (return at the end of the sequence) good enough.\n", + " You can do this by including output gate, forget gate, and fully connected gates, in this order.\n", + "1. Check if the reward redistribution makes sense.\n", + " - Look at the output of the contribution analysis, e.g. the differences of predictions of the LSTM at each sequence position, and check if the reward is redistributed to earlier positions in the sequence.\n", + " - Check if the model is over-fitting. If it is, increase the number of samples or reduce the model complexity.\n", + " - At this point you can get a feeling for if RUDDER might help in your task or not.\n", + "1. Set up a lessons buffer to train the reward redistribution model during training of the agent.\n", + " - From the previous points you should get a feeling for how large the dataset has to be for the LSTM to learn properly.\n", + " - I suggest a lessons buffer that prioritizes samples with higher reward redistribution model loss and that increases the variance of sample returns in the buffer.\n", + "1. Use the reward redistribution to train an agent, e.g. via with PPO.\n", + " - For actor-critic based methods, you can replace the reward signal that the critic would be trained on by the redistributed reward.\n", + " - If your environment has intermediate rewards, you might want to mix the original reward signal with the redistributed reward.\n", + " \n", + "The following sections will show an example for points 1-3, which can serve as pre-assessment if RUDDER might help in your task." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

Importing packages

\n", + "We'll start by importing the required packages for this guide. I will use my repository widis-lstm-tools v0.4 for the simplified LSTM. You can install it via\n", + "\n", + "```bash\n", + "pip install git+https://github.com/widmi/widis-lstm-tools\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import torch\n", + "import tqdm\n", + "from torch.utils.data import Dataset\n", + "from matplotlib import pyplot as plt\n", + "from widis_lstm_tools.nn import LSTMLayer\n", + "\n", + "# Prepare some random generators for later\n", + "rnd_gen = np.random.RandomState(seed=123)\n", + "_ = torch.manual_seed(123)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

Creating an example task with delayed reward

\n", + "\n", + "For simplicity, we will create samples for a trivial 1D environment, which we traverse with a random policy. Feel free to replace this environment with samples from your task.\n", + "\n", + "In this environment the agent starts at position 0 and can choose between moving right or left at each timestep, which will increase or decrease the agents position by +1 or -1 respectively.\n", + "Actions that would leave the position range [-6, 6] are ignored, so the number of unique states is restricted to 13. The state only consists of the current position. The agent can take a total of 50 actions per episode, that is each game sequence has a length of 50.\n", + "\n", + "Or visually illustrated:\n", + "\n", + "

\n", + " \n", + "

\n", + "\n", + "If the agent is in state with position 2 it gains +1 reward. \n", + "We turn this task into a delayed reward task where we know what the immediate reward would look like. For this we assume that the reward is not shown to the agent immediately but instead the **accumulated reward is shown at the last timestep**.\n", + "Note that this is not an MDP anymore but for reward redistribution with an LSTM this will not bother us." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "config_file_path: /mnt/484A4CAB4A4C9798/GoogleDrive/Maestria-Drive/HiWi/mdp-playground/experiments\n", + "Number of seeds for environment: 10\n", + "Configuration numbers that will be run: all\n", + "(8, 8, 2, 1, 0.25, False, 0, 0, 0, 0)\n", + "Passed config: {'seed': 0, 'state_space_type': 'discrete', 'action_space_type': 'discrete', 'generate_random_mdp': True, 'repeats_in_sequences': False, 'reward_scale': 1.0, 'completely_connected': True, 'state_space_size': 8, 'action_space_size': 8, 'delay': 2, 'sequence_length': 1, 'reward_density': 0.25, 'make_denser': False, 'terminal_state_density': 0, 'transition_noise': 0, 'reward_noise': . at 0x7f5103786a60>, 'reward_noise_std': 0, 'dummy_seed': 0} \n", + "\n", + "\u001b[32;1m========================================================Initialising Toy MDP========================================================\u001b[0m\n", + "Current working directory: /mnt/484A4CAB4A4C9798/GoogleDrive/Maestria-Drive/HiWi/mdp-playground\n", + "Env SEED set to: 0. Returned seed from Gym: 0\n", + "transition_matrix inited to:\n", + "[[7 6 0 3 4 5 2 1]\n", + " [7 6 4 1 2 0 3 5]\n", + " [5 7 4 6 3 1 0 2]\n", + " [2 4 3 6 5 7 1 0]\n", + " [3 6 4 2 7 1 5 0]\n", + " [4 2 1 5 6 3 0 7]\n", + " [5 7 1 4 6 2 3 0]\n", + " [5 6 1 3 2 0 7 4]]\n", + "Python type of state: \n", + "rewardable_sequences: {(7,): 1.0, (4,): 1.0}\n", + "MDP Playground toy env instantiated with config: {'seed': 0, 'state_space_type': 'discrete', 'action_space_type': 'discrete', 'generate_random_mdp': True, 'repeats_in_sequences': False, 'reward_scale': 1.0, 'completely_connected': True, 'state_space_size': 8, 'action_space_size': 8, 'delay': 2, 'sequence_length': 1, 'reward_density': 0.25, 'make_denser': False, 'terminal_state_density': 0, 'transition_noise': 0, 'reward_noise': . at 0x7f5103786a60>, 'reward_noise_std': 0, 'dummy_seed': 0, 'terminal_states': array([], dtype=float64), 'relevant_init_state_dist': array([0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125]), 'transition_function': . at 0x7f5103786d90>}\n", + "125\n" + ] + } + ], + "source": [ + "import importlib\n", + "import mdp_playground\n", + "from mdp_playground.envs import RLToyEnv\n", + "\n", + "import sys, os\n", + "import argparse\n", + "import importlib\n", + "\n", + "import default_config\n", + "from run_experiments_baselines import *\n", + "\n", + "class Environment(Dataset):\n", + " def __init__(self, n_samples: int, max_timestep: int, rnd_gen: np.random.RandomState):\n", + " \"\"\"Our simple 1D environment as PyTorch Dataset\"\"\"\n", + " super(Environment, self).__init__()\n", + " # arguments\n", + " config_file = './experiments/a3c_del.py'\n", + " config_num = None\n", + "\n", + " # init code\n", + " config_file_path = os.path.abspath('/'.join(config_file.split('/')[:-1]))\n", + " sys.path.insert(1, config_file_path)\n", + " import a3c_del as config\n", + " print(\"config_file_path:\", config_file_path)\n", + "\n", + " #config = importlib.import_module(config_file.split('/')[-1], package=None)\n", + " print(\"Number of seeds for environment:\", config.num_seeds)\n", + " print(\"Configuration numbers that will be run:\", \"all\" if config_num is None else config_num)\n", + "\n", + "\n", + " #------------------------- Variable configurations ----------------------------#\n", + " config, var_agent_configs, var_model_configs = agent_to_baselines(config)\n", + " var_configs_deepcopy = copy.deepcopy(config.var_configs) #hack because this needs to be read in on_train_result and trying to read config there raises an error because it's been imported from a Python module and I think they try to reload it there.\n", + "\n", + " if \"env\" in config.var_configs:\n", + " var_env_configs = config.var_configs[\"env\"] #hack\n", + " else:\n", + " var_env_configs = []\n", + "\n", + " #---------- Compute cartesian product of configs ----------------#\n", + " # cartesian_product_configs = cartesian_prod(args, config)\n", + " if config_num is None:\n", + " cartesian_product_configs = config.cartesian_product_configs\n", + " else:\n", + " cartesian_product_configs = [config.cartesian_product_configs[config_num]]\n", + "\n", + " #------------ Run every configuration ------------------ #\n", + " pp = pprint.PrettyPrinter(indent=4)\n", + " # for i, current_config in enumerate(cartesian_product_configs):\n", + " # print(\"Configuration: %d \\t %d remaining\"%(i, len(cartesian_product_configs) - i ))\n", + "\n", + " current_config = cartesian_product_configs[20]\n", + " print(current_config)\n", + " #------------ Dictionaries setup ------------------ #\n", + " agent_config, model_config, env_config = process_dictionaries(config, current_config, var_env_configs, var_agent_configs, var_model_configs)\n", + "\n", + " #------------ Env init ------------------ #\n", + " # Generate random action sequences\n", + " env = gym.make(env_config['env'],**env_config['env_config'])\n", + " \n", + " # Generate random action sequences\n", + " total_ep = 15\n", + " lessons_buffer = []\n", + " for e in range(n_samples):\n", + " s = env.reset()\n", + " lessons_buffer.append([])\n", + " for ts in range(max_timestep):\n", + " a = env.action_space.sample()\n", + " ns, r, d, _ = env.step(a)\n", + " # print(s, a, r)\n", + " lessons_buffer[e].append([s, a, r, ns])\n", + " s = ns\n", + " # shape = (n_samples, max_timestep, 4)\n", + " lessons_buffer = np.array(lessons_buffer)\n", + " \n", + " a = np.expand_dims(lessons_buffer[:, :, 1], -1).astype(int)\n", + " n_actions = env.action_space.n # For discrete action_spaces\n", + " b = np.zeros((a.size, n_actions + 1))\n", + " # use advanced indexing to get one-hot encoding\n", + " b[np.arange(a.size), a.ravel()] = 1\n", + " # reshape to original form\n", + " actions_onehot = b.reshape(a.shape[:-1] + (n_actions + 1,))\n", + " \n", + " # Generate observations from action sequences\n", + " obs = np.expand_dims(lessons_buffer[:, :, 0], -1).astype(int)\n", + " n_obs = env.observation_space.n # For discrete action_spaces\n", + " b = np.zeros((obs.size, n_obs + 1))\n", + " # use advanced indexing to get one-hot encoding\n", + " b[np.arange(obs.size), obs.ravel()] = 1\n", + " # reshape to original form\n", + " observations_onehot = b.reshape(obs.shape[:-1] + (n_obs + 1,))\n", + " \n", + " # Calculate rewards (sum over coin position for all timesteps)\n", + " rewards = lessons_buffer[:, :, 2]\n", + " \n", + " self.actions = actions_onehot\n", + " self.observations = observations_onehot\n", + " self.rewards = rewards\n", + " \n", + " def __len__(self):\n", + " return self.rewards.shape[0]\n", + " \n", + " def __getitem__(self, idx):\n", + " return self.observations[idx], self.actions[idx], self.rewards[idx]\n", + "\n", + " \n", + "n_positions = 13\n", + "env = Environment(n_samples=1000, max_timestep=100, rnd_gen=rnd_gen)\n", + "env_loader = torch.utils.data.DataLoader(env, batch_size=8, num_workers=4)\n", + "\n", + "print(len(env_loader))\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Let's take a look at one of the samples:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(100, 9)\n", + "[4 5 5 2 6 7 5 6 3 0 7 7 7 6 1 4 7 4 7 4 6 4 0 0 6 6 6 4 3 0 6 0 2 4 2 0 1\n", + " 3 7 0 1 6 7 1 1 0 2 2 6 2 7 5 5 3 4 1 4 1 1 5 3 6 5 3 4 5 1 7 2 2 2 4 4 4\n", + " 1 2 0 3 7 6 0 5 5 7 5 6 1 4 2 5 0 5 1 1 5 2 3 7 5 5]\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "obs0, a0, r0 = env.__getitem__(3)\n", + "obs1, a1, r1 = env.__getitem__(25)\n", + "fig, axes = plt.subplots(3, 2, figsize=(8, 4.5), dpi=100)\n", + "print(obs0.shape)\n", + "mean = np.mean(obs0.argmax(-1))\n", + "print(obs1.argmax(-1))\n", + "axes[0, 0].plot(obs0.argmax(-1))\n", + "axes[0, 1].plot(obs1.argmax(-1))\n", + "axes[0, 0].set_ylim(0, 8)\n", + "axes[0, 1].set_ylim(0, 8)\n", + "axes[0, 0].xaxis.grid(True)\n", + "axes[0, 1].xaxis.grid(True)\n", + "axes[0, 0].set_title('observations (sample 1)')\n", + "axes[0, 1].set_title('observations (sample 2)')\n", + "axes[0, 0].set_xlabel('time (environment steps)')\n", + "axes[0, 1].set_xlabel('time (environment steps)')\n", + "\n", + "axes[1, 0].plot(a0.argmax(-1))\n", + "axes[1, 1].plot(a1.argmax(-1))\n", + "axes[1, 0].xaxis.grid(True)\n", + "axes[1, 1].xaxis.grid(True)\n", + "axes[1, 0].set_title('actions (sample 1)')\n", + "axes[1, 1].set_title('actions (sample 2)')\n", + "axes[1, 0].set_xlabel('time (environment steps)')\n", + "axes[1, 1].set_xlabel('time (environment steps)')\n", + "\n", + "axes[2, 0].plot(r0)\n", + "axes[2, 1].plot(r1)\n", + "axes[2, 0].xaxis.grid(True)\n", + "axes[2, 1].xaxis.grid(True)\n", + "axes[2, 0].set_title('original rewards (sample 1)')\n", + "axes[2, 1].set_title('original rewards (sample 2)')\n", + "axes[2, 0].set_xlabel('time (environment steps)')\n", + "axes[2, 1].set_xlabel('time (environment steps)')\n", + "\n", + "fig.tight_layout()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "... we can see that we created a delayed reward task. Everytime the agent is at position 2 it receives +1 reward at the end of the sequence.\n", + "\n", + "Now let's see what RUDDER can do for us in such a case." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

Training a reward redistribution model

\n", + "\n", + "We will now train an LSTM model to perform reward redistribution on this task." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

Defining the model

\n", + "\n", + "Our model will consist of one LSTM layer with 16 cells. We will feed concatenated actions and observations timestep by timestep into the network. We could also use separate networks to preprocess actions and observations. In our experiments it helped to have the number of action- and observation features similar before concatenation. In practice it might not always be necessary to also feed the deltas of the observations, like we did in our paper and for the Atari games. In this example I will omit this.\n", + "\n", + "We will start with a simplified LSTM model without forget gate and without output gate. Additionally, we will only connect the input gate to the recurrent connections and the cell input to the forward connections. The output function of our LSTM will be linear since we are performing regression to predict the return value.\n", + "\n", + "In case our model would not be good enough to predict the return at the end of the sequence, we would have to increase the model complexity until it is good enough. You can do this by including output gate, forget gate, and fully connected gates, in this order." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "class Net(torch.nn.Module):\n", + " def __init__(self, n_positions, n_actions, n_lstm):\n", + " super(Net, self).__init__()\n", + " \n", + " # This will create an LSTM layer where we will feed the concatenate\n", + " self.lstm1 = LSTMLayer(\n", + " in_features=n_positions+n_actions, out_features=n_lstm, inputformat='NLC',\n", + " # cell input: initialize weights to forward inputs with xavier, disable connections to recurrent inputs\n", + " w_ci=(torch.nn.init.xavier_normal_, False),\n", + " # input gate: disable connections to forward inputs, initialize weights to recurrent inputs with xavier\n", + " w_ig=(False, torch.nn.init.xavier_normal_),\n", + " # output gate: disable all connection (=no forget gate) and disable bias\n", + " w_og=False, b_og=False,\n", + " # forget gate: disable all connection (=no forget gate) and disable bias\n", + " w_fg=False, b_fg=False,\n", + " # LSTM output activation is set to identity function\n", + " a_out=lambda x: x\n", + " )\n", + " \n", + " # After the LSTM layer, we add a fully connected output layer\n", + " self.fc_out = torch.nn.Linear(n_lstm, 1)\n", + " \n", + " def forward(self, observations, actions):\n", + " # Process input sequence by LSTM\n", + " lstm_out, *_ = self.lstm1(torch.cat([observations, actions], dim=-1),\n", + " return_all_seq_pos=True # return predictions for all sequence positions\n", + " )\n", + " net_out = self.fc_out(lstm_out)\n", + " return net_out\n", + "\n", + "\n", + "# Create Network\n", + "device = 'cpu'\n", + "net = Net(n_positions=n_positions, n_actions=2, n_lstm=16)\n", + "_ = net.to(device)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

Defining the loss function

\n", + "\n", + "As mentioned in the overview, we will train on two tasks:\n", + "\n", + "1. The **main task** to train on is to predict the return of each sample at the end of the sequence.\n", + "2. The **auxiliary task** is to train the model to predict the final return at every sequence position. This will allow us to perform contribution analysis via differences of predictions. In some cases this helps to push the reward further back in time. Predicting the final return at every sequence position will typically be a lot more difficult for the LSTM since it needs to predict the unknown future. However, the LSTM does not need to be perfect at this task since having a correct return decomposition depends only on the prediction at the last timestep (main task). \n", + "\n", + "We do not have any intermediate rewards in the sequence, so we will only use these two tasks (main task, auxiliary task). We will downweight the auxiliary task with a factor of 0.5. Given the model output (=predictions) and the sequence of rewards we compute our loss as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "def lossfunction(predictions, rewards):\n", + " returns = rewards.sum(dim=1)\n", + " # Main task: predicting return at last timestep\n", + " main_loss = torch.mean(predictions[:, -1] - returns) ** 2\n", + " # Auxiliary task: predicting final return at every timestep ([..., None] is for correct broadcasting)\n", + " aux_loss = torch.mean(predictions[:, :] - returns[..., None]) ** 2\n", + " # Combine losses\n", + " loss = main_loss + aux_loss * 0.5\n", + " return loss" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

Training the model

\n", + "\n", + "Now we train our model:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\r", + " 0%| | 0/10000 [00:00\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 15\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 16\u001b[0m \u001b[0;31m# Get outputs for network\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 17\u001b[0;31m \u001b[0moutputs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnet\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mobservations\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mobservations\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mactions\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mactions\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 18\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 19\u001b[0m \u001b[0;31m# Calculate loss, do backward pass, and update\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/torch/nn/modules/module.py\u001b[0m in \u001b[0;36m_call_impl\u001b[0;34m(self, *input, **kwargs)\u001b[0m\n\u001b[1;32m 887\u001b[0m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_slow_forward\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0minput\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 888\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 889\u001b[0;31m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mforward\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0minput\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 890\u001b[0m for hook in itertools.chain(\n\u001b[1;32m 891\u001b[0m \u001b[0m_global_forward_hooks\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalues\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m\u001b[0m in \u001b[0;36mforward\u001b[0;34m(self, observations, actions)\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[0;31m# Process input sequence by LSTM\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 25\u001b[0m lstm_out, *_ = self.lstm1(torch.cat([observations, actions], dim=-1),\n\u001b[0;32m---> 26\u001b[0;31m \u001b[0mreturn_all_seq_pos\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m \u001b[0;31m# return predictions for all sequence positions\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 27\u001b[0m )\n\u001b[1;32m 28\u001b[0m \u001b[0mnet_out\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfc_out\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlstm_out\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/torch/nn/modules/module.py\u001b[0m in \u001b[0;36m_call_impl\u001b[0;34m(self, *input, **kwargs)\u001b[0m\n\u001b[1;32m 887\u001b[0m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_slow_forward\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0minput\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 888\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 889\u001b[0;31m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mforward\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0minput\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 890\u001b[0m for hook in itertools.chain(\n\u001b[1;32m 891\u001b[0m \u001b[0m_global_forward_hooks\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalues\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/widis_lstm_tools/nn.py\u001b[0m in \u001b[0;36mforward\u001b[0;34m(self, x, return_all_seq_pos, true_seq_lens, reset_state)\u001b[0m\n\u001b[1;32m 985\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 986\u001b[0m \u001b[0;31m# Calculate activations for LSTM inlets and append them to self.lstm_inlets_activations\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 987\u001b[0;31m \u001b[0mcell_rets\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__apply_cell__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mh\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mc\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 988\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mc\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0mcell_rets\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 989\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mh\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0mcell_rets\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/widis_lstm_tools/nn.py\u001b[0m in \u001b[0;36m__apply_cell__\u001b[0;34m(self, fwd_inputs, h_old, c_old)\u001b[0m\n\u001b[1;32m 892\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mfwd_input\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0munbind_inputs\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfwd_inputs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 893\u001b[0m \u001b[0;31m# Calculate activations for LSTM inlets and append them to self.lstm_inlets_activations\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 894\u001b[0;31m \u001b[0mcell_rets\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlstm_cell\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcell\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfwd_input\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mh_old\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mc_old\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 895\u001b[0m \u001b[0mc_old\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcell_rets\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 896\u001b[0m \u001b[0mh_old\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcell_rets\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/widis_lstm_tools/nn.py\u001b[0m in \u001b[0;36mcell\u001b[0;34m(self, fwd_inputs, rec_input, c_old)\u001b[0m\n\u001b[1;32m 235\u001b[0m \u001b[0mContains\u001b[0m \u001b[0mcell\u001b[0m \u001b[0mstate\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcell\u001b[0m \u001b[0moutput\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcell\u001b[0m \u001b[0minput\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0minput\u001b[0m \u001b[0mgate\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0moutput\u001b[0m \u001b[0mgate\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mforget\u001b[0m \u001b[0mgate\u001b[0m \u001b[0mactivations\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 236\u001b[0m \"\"\"\n\u001b[0;32m--> 237\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__traced_cell__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfwd_inputs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrec_input\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mc_old\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mw_fwd_cat\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mw_rec_cat\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mb_cat\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 238\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 239\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mcell_tickersteps\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrec_input\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mc_old\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/widis_lstm_tools/nn.py\u001b[0m in \u001b[0;36m__cell_python__\u001b[0;34m(self, fwd_input, rec_input, c_old, w_fwd_cat, w_rec_cat, b)\u001b[0m\n\u001b[1;32m 276\u001b[0m \u001b[0;31m# Compute activations for concatenated weights and split them to inlets\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 277\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mn_fwd_features\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 278\u001b[0;31m \u001b[0mnet_fwds_cat\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmm\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfwd_input\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mw_fwd_cat\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 279\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 280\u001b[0m \u001b[0mnet_fwds_cat\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mzeros_like\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfwd_input\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mRuntimeError\u001b[0m: mat1 and mat2 shapes cannot be multiplied (8x18 and 15x16)" + ] + } + ], + "source": [ + "optimizer = torch.optim.Adam(net.parameters(), lr=1e-3, weight_decay=1e-5)\n", + "\n", + "update = 0\n", + "n_updates = 10000\n", + "running_loss = 100.\n", + "progressbar = tqdm.tqdm(total=n_updates)\n", + "while update < n_updates:\n", + " for data in env_loader:\n", + " # Get samples\n", + " observations, actions, rewards = data\n", + " observations, actions, rewards = observations.to(device), actions.to(device), rewards.to(device)\n", + " \n", + " # Reset gradients\n", + " optimizer.zero_grad()\n", + " \n", + " # Get outputs for network\n", + " outputs = net(observations=observations, actions=actions)\n", + " \n", + " # Calculate loss, do backward pass, and update\n", + " loss = lossfunction(outputs[..., 0], rewards)\n", + " loss.backward()\n", + " running_loss = running_loss*0.99 + loss*0.01\n", + " optimizer.step()\n", + " update += 1\n", + " progressbar.set_description(f\"Loss: {running_loss:8.4f}\")\n", + " progressbar.update(1)\n", + "\n", + "progressbar.close()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

Computing the reward redistribution

\n", + "\n", + "We can now compute the reward redistribution as the differences of predictions of our trained model. In the optimal case, the reward would be redistributed to the actions that caused the reward and return. In practice, it will be distributed to what the model uses to predict the return, which might e.g. be prominent states. This is where the auxiliary task will help to move the reward further back.\n", + "Naturally, the better the LSTM predictions are, the better this reward redistribution will be.\n", + "\n", + "Let's compute the reward redistribution using our trained model:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Load 2 samples\n", + "obs0, a0, r0 = env.__getitem__(3)\n", + "obs1, a1, r1 = env.__getitem__(25)\n", + "\n", + "# Apply our reward redistribution model to the samples\n", + "observations = torch.stack([torch.Tensor(obs0).to(device), torch.Tensor(obs1).to(device)], dim=0)\n", + "actions = torch.stack([torch.Tensor(a0).to(device), torch.Tensor(a1).to(device)], dim=0)\n", + "rewards = torch.stack([torch.Tensor(r0).to(device), torch.Tensor(r1).to(device)], dim=0)\n", + "predictions = net(observations=observations.to(device), actions=actions.to(device))[..., 0]\n", + "\n", + "# Use the differences of predictions as redistributed reward\n", + "redistributed_reward = predictions[:, 1:] - predictions[:, :-1]\n", + "\n", + "# For the first timestep we will take (0-predictions[:, :1]) as redistributed reward\n", + "redistributed_reward = torch.cat([predictions[:, :1], redistributed_reward], dim=1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can also enforce that the new and the original sequence have the same return.\n", + "We will do this by calculating the prediction error and distributing the correction for the error equally over all sequence position:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Calculate prediction error\n", + "returns = rewards.sum(dim=1)\n", + "predicted_returns = redistributed_reward.sum(dim=1)\n", + "prediction_error = returns - predicted_returns\n", + "\n", + "# Distribute correction for prediction error equally over all sequence positions\n", + "redistributed_reward += prediction_error[:, None] / redistributed_reward.shape[1]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

Inspecting the reward redistribution

\n", + "\n", + "Finally, let's take a look at the reward redistribution for our 2 samples:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Let's plot our samples with the redistributed rewards:\n", + "redistributed_reward = redistributed_reward.cpu().detach().numpy()\n", + "rr0, rr1 = redistributed_reward[0], redistributed_reward[1]\n", + "\n", + "fig, axes = plt.subplots(4, 2, figsize=(8, 6), dpi=100)\n", + "axes[0, 0].plot(obs0.argmax(-1) - 6)\n", + "axes[0, 1].plot(obs1.argmax(-1) - 6)\n", + "axes[0, 0].set_ylim(-6, 6)\n", + "axes[0, 1].set_ylim(-6, 6)\n", + "axes[0, 0].axhline(2, linestyle='--', color='r')\n", + "axes[0, 1].axhline(2, linestyle='--', color='r')\n", + "axes[0, 0].xaxis.grid(True)\n", + "axes[0, 1].xaxis.grid(True)\n", + "axes[0, 0].set_title('observations (sample 1)')\n", + "axes[0, 1].set_title('observations (sample 2)')\n", + "axes[0, 0].set_xlabel('time (environment steps)')\n", + "axes[0, 1].set_xlabel('time (environment steps)')\n", + "\n", + "axes[1, 0].plot(a0.argmax(-1))\n", + "axes[1, 1].plot(a1.argmax(-1))\n", + "axes[1, 0].xaxis.grid(True)\n", + "axes[1, 1].xaxis.grid(True)\n", + "axes[1, 0].set_title('actions (sample 1)')\n", + "axes[1, 1].set_title('actions (sample 2)')\n", + "axes[1, 0].set_xlabel('time (environment steps)')\n", + "axes[1, 1].set_xlabel('time (environment steps)')\n", + "\n", + "axes[2, 0].plot(r0)\n", + "axes[2, 1].plot(r1)\n", + "axes[2, 0].xaxis.grid(True)\n", + "axes[2, 1].xaxis.grid(True)\n", + "axes[2, 0].set_title('original rewards (sample 1)')\n", + "axes[2, 1].set_title('original rewards (sample 2)')\n", + "axes[2, 0].set_xlabel('time (environment steps)')\n", + "axes[2, 1].set_xlabel('time (environment steps)')\n", + "\n", + "axes[3, 0].plot(rr0)\n", + "axes[3, 1].plot(rr1)\n", + "axes[3, 0].xaxis.grid(True)\n", + "axes[3, 1].xaxis.grid(True)\n", + "axes[3, 0].set_title('redistributed rewards (sample 1)')\n", + "axes[3, 1].set_title('redistributed rewards (sample 2)')\n", + "axes[3, 0].set_xlabel('time (environment steps)')\n", + "axes[3, 1].set_xlabel('time (environment steps)')\n", + "\n", + "fig.tight_layout()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can see that the reward that was originally only given at the end is moved to actions that bring the agent closer to position 2.\n", + "\n", + "That means that **we do not recover the environment** where the agent receives +1 reward for being at position 2 **but instead get an environment with rewards that have even shorter delay**, since the actions towards position 2 are immediately rewarded...\n", + "\n", + "... and we achieved all of this with a **supervised ML approach**!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

A note on LSTM training

\n", + "\n", + "Take a look at the cell states and activations to check if your LSTM is doing something useful or just overfits to e.g. the sequence length or goes into saturation somewhere.\n", + "\n", + "The LSTM states after training would look something like this for sample 1 in the previous plots:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Plost LSTM states for first sample of last processed minibatch\n", + "net.lstm1.plot_internals(filename=None, show_plot=True, mb_index=0, fdict=dict(figsize=(8, 8), dpi=100))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

A note on contribution analysis

\n", + "\n", + "We found **differences of predictions** to be a well suited method for contribution analysis in our experiments. Mainly due to three nice properties:\n", + "\n", + "1. The **reward redistribution model already performs some averaging over the future** (since it has to predict the final return early in the sequence). This makes learning for the underlying RL agent/method easier. However, this is also the downside of this approach, since the reward redistribution model now not only has to learn to predict the return at the last sequence position. Other contribution analysis methods, such as integrated gradients or layer-wise relevance propagation, do not require the reward redistribution model to learn this prediction at every sequence position, since they can perform contribution analysis based on the prediction at the last sequence position. However, this also means that the agent might receive reward for events that happen in the future, if the contribution analysis comes from the end of the completed episode sequence.\n", + "2. The reward redistribution model trained on predicting the return at the last sequence position will use information from arbitrary sequence positions to do its prediction. However, we would like to **redistribute the reward as far back to the sequence beginning as possible** to decrease the delay between action and corresponding reward. That means we want the reward redistribution model to **detect information that is useful for the prediction of the return as early in the sequence as possible**. And this is exactly what this auxiliary task does. E.g.: Predicting the outcome of a football game is easy by counting when a team scores a goal. The model is therefore likely to use these prominent events for its prediction. Since we are interested not only in assigning reward to those events but even further back to the actions that caused it (some good play that lead to the goal), we have to push the model to do its prediction as early as possible.\n", + "3. Using the differences of the predictions at each sequence position implies that **we can easily perform contribution analysis on incomplete sequences**. Hence, we do not need to need to wait until the episode sequence is completed to perform contribution analysis and train our RL agent/method with the redistributed reward. In practice, **we can keep training the reward redistribution model on the completed episodes in the lessons buffer** in the background while we use the same reward redistribution model to perform **online reward redistribution on new sequences** that are sampled from the environment. This allows for **training an agent with redistributed reward in an online fashion**." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "

What is left to do?

\n", + "\n", + "At this point you might already be able to assess whether RUDDER helps in your task. You then have to set up a lessons buffer to train your reward redistribution model as the policy changes and feed your RL agent/method with the redistributed reward, as described in points 4 and 5 in the overview.\n", + "\n", + "For more details please see our [blog](https://www.jku.at/index.php?id=16426), [paper](https://arxiv.org/abs/1806.07857), and our [RUDDER repo](https://github.com/ml-jku/rudder).\n", + "\n", + "Many thanks to Johannes Brandstetter for proof-reading and testing!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I hope this tutorial was able to help you and wish you the best for your RL endeavors!\n", + "\n", + "-- Michael Widrich (widi)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.12" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/run_experiments_baselines.py b/run_experiments_baselines.py index 57755e9..ab0a78d 100644 --- a/run_experiments_baselines.py +++ b/run_experiments_baselines.py @@ -60,6 +60,7 @@ def create_gym_env_wrapper_frame_stack_atari(config): #hack ###TODO remove? gew = GymEnvWrapper(ae, **config) ##IMP Had initially thought to put this config in config["GymEnvWrapper"] but because of code below which converts var_env_configs to env_config, it's best to leave those configs as top level configs in the dict! return gew + class CustomCallback(sb.common.callbacks.BaseCallback): """ Callback for evaluating an agent. @@ -94,6 +95,8 @@ def __init__( self.var_configs = var_configs self.last_episode_count = 0 self.episodes_in_iter = 0 + self.best_eval_mean = 0 + # self.best_train_return = 0 # Convert to VecEnv for consistency if not isinstance(eval_env, VecEnv): eval_env = DummyVecEnv([lambda: eval_env]) @@ -103,17 +106,18 @@ def __init__( assert eval_env.num_envs == 1, "You must pass only one environment for evaluation" self.eval_env = eval_env - - #evaluate policy when step % eval_freq == 0, return rewards and lengths list of n_eval_episodes elements + + # evaluate policy when step % eval_freq == 0, return rewards and lengths list of n_eval_episodes elements def _on_step(self): - #count steps + # count steps self.total_timesteps+=1 - #training log - if(self.total_timesteps % self.timesteps_per_iteration == 0): #training iteration done, log train csv + # training log + # training iteration done, log train csv + if(self.total_timesteps % self.timesteps_per_iteration == 0): self.write_train_result() - self.training_iteration+=1 + self.training_iteration += 1 - #evaluation + # evaluation if self.eval_freq > 0 and self.n_calls % self.eval_freq == 0: # Sync training and eval env if there is VecNormalize sync_envs_normalization(self.training_env, self.eval_env) @@ -125,34 +129,48 @@ def _on_step(self): render=False, deterministic=self.deterministic, return_episode_rewards=True, - ) - #write evaluation csv + ) + + # write evaluation csv self.write_eval_results(episode_rewards, episode_lengths) mean_reward, std_reward = np.mean(episode_rewards), np.std(episode_rewards) mean_ep_length, std_ep_length = np.mean(episode_lengths), np.std(episode_lengths) + if(self.best_eval_mean < mean_reward): + self.model.save("%s_best_eval" % (self.file_name)) + self.best_eval_mean = mean_reward + if self.verbose > 0: print(f"Eval num_timesteps={self.num_timesteps}, " f"episode_reward={mean_reward:.2f} +/- {std_reward:.2f}") print(f"Episode length: {mean_ep_length:.2f} +/- {std_ep_length:.2f}") return True + # def _on_rollout_end(self): + # env = self.training_env + # if isinstance(self.training_env, VecEnv): + # env = env.unwrapped.envs[0] # only using one environment + # episode_rewards = env.get_episode_rewards() + # if(episode_rewards[-1] > self.best_train_return): + # self.model.save("%s_best_train" % (self.file_name)) + # self.best_train_return = episode_rewards[-1] + # Used in callback after every episode has ended during evaluation # replaces: def on_episode_end(info) def write_eval_results(self, episode_rewards, episode_lengths): eval_filename = self.file_name + '_eval.csv' - fout = open(eval_filename, 'a') #hardcoded + fout = open(eval_filename, 'a') # hardcoded for reward_this_episode, length_this_episode in zip(episode_rewards, episode_lengths): fout.write(str(reward_this_episode[0]) + ' ' + str(length_this_episode) + "\n") fout.close() - + # Write training stats to CSV file at end of every training iteration def write_train_result(self): env, training_iteration, total_timesteps = self.training_env, self.training_iteration, self.total_timesteps - file_name, config_algorithm, var_configs = self.file_name, self.config_algorithm, self.var_configs + config_algorithm, var_configs = self.config_algorithm, self.var_configs if isinstance(env, VecEnv): - env = env.unwrapped.envs[0]#only using one environment + env = env.unwrapped.envs[0] # only using one environment #A2C can handle multiple envs.. # if(self.config_algorithm == "A2C" or self.config_algorithm =="A3C"): @@ -182,14 +200,15 @@ def write_train_result(self): # Write train statss episode_rewards = env.get_episode_rewards() episode_lengths = env.get_episode_lengths() - #update episodes + # update episodes n_episodes = len(episode_rewards) self.episodes_in_iter = n_episodes - self.last_episode_count - if(self.episodes_in_iter == 0):#no episodes in iteration - if(n_episodes) == 0: #special case when there are no episodes so far - episode_reward_mean = np.sum(env.rewards)#cummulative reward so far - episode_len_mean = env.get_total_steps()#all steps so far - else:#iteration end, no episode end + if(self.episodes_in_iter == 0): # no episodes in iteration + if(n_episodes) == 0: # special case when there are no episodes so far + episode_reward_mean = np.sum(env.rewards) # cummulative reward so far + episode_len_mean = env.get_total_steps() # all steps so far + else: + # iteration end, no episode end # start = self.timesteps_per_iteration*training_iteration # episode_reward_mean = np.sum(env.rewards[start:]) # episode_length_mean = self.timesteps_per_iteration @@ -197,12 +216,15 @@ def write_train_result(self): episode_length_mean = self.timesteps_per_iteration else: # episode stats are from all steps taken in env then we need to take mean over "iterations": - #start , stop = self.last_episode_count, self.last_episode_count + self.episodes_in_iter - 1 - episode_reward_mean = np.mean(episode_rewards[self.last_episode_count : ]) - episode_length_mean = np.mean(episode_lengths[self.last_episode_count : ]) + # start , stop = self.last_episode_count, self.last_episode_count + self.episodes_in_iter - 1 + episode_reward_mean = np.mean(episode_rewards[self.last_episode_count:]) + episode_length_mean = np.mean(episode_lengths[self.last_episode_count:]) self.last_episode_count = n_episodes - fout.write(str(total_timesteps) + ' ' + str(episode_reward_mean) + - ' ' + str(episode_length_mean) + '\n') # timesteps_total always HAS to be the 1st written: analysis.py depends on it + + # timesteps_total always HAS to be the 1st written: analysis.py depends on it + fout.write(str(total_timesteps) + ' ' + + str(episode_reward_mean) + + ' ' + str(episode_length_mean) + '\n') fout.close() # We did not manage to find an easy way to log evaluation stats for Ray without the following hack which demarcates the end of a training iteration in the evaluation stats file @@ -214,6 +236,7 @@ def write_train_result(self): #info["result"]["callback_ok"] = True return True + def parse_args(): parser = argparse.ArgumentParser(description=__doc__) # docstring at beginning of the file is stored in __doc__ parser.add_argument('-c', '--config-file', dest='config_file', action='store', default='default_config', @@ -785,13 +808,14 @@ def main(args): config_algorithm = config.algorithm, var_configs = var_configs_deepcopy) #Train learn_params = {"callback": csv_callbacks, - "total_timesteps": timesteps_total} + "total_timesteps": int(timesteps_total)} if(config.algorithm == "DDPG"): #Log interval is handled differently for each algorithm, e.g. each log_interval episodes(DQN) or log_interval steps(DDPG). learn_params["log_interval"] = timesteps_per_iteration else: learn_params["log_interval"] = timesteps_per_iteration//10 model.learn(**learn_params) + model.save('%s_last'%(args.exp_name)) end = time.time() print("No. of seconds to run:", end - start) diff --git a/test_cave_analysis.py b/test_cave_analysis.py index 9452bbe..863137d 100644 --- a/test_cave_analysis.py +++ b/test_cave_analysis.py @@ -2,12 +2,13 @@ from mdp_playground.analysis.mdpp_to_cave import MDPPToCave import os -files_dir = "/mnt/484A4CAB4A4C9798/GoogleDrive/Maestria-Drive/HiWi/mdp_files" +files_dir = "/mnt/484A4CAB4A4C9798/GoogleDrive/Maestria-Drive/HiWi/mdp_files/" #baselines" experiments = { # "a3c_seq" : "%s/a3c_seq/"%files_dir, # "a3c_lstm_seq" : "%s/a3c_lstm_seq/"%files_dir, # "a3c_del" : "%s/a3c_del/"%files_dir, - "a3c_lstm_del" : "%s/a3c_lstm_del/"%files_dir, +# "a3c_lstm_del" : "%s/a3c_lstm_del/"%files_dir, + "dqn_seq_del": files_dir } #The converted mdpp csvs will be stored in output_dir @@ -27,6 +28,6 @@ file_format = "BOHB", show_jupyter=True, ) -cave.performance_table() -cave.local_parameter_importance() -# cave.cave_fanova() \ No newline at end of file +# cave.performance_table() +# cave.local_parameter_importance() +cave.cave_fanova() \ No newline at end of file From 65285cc79a24740466d7a2d1d87aaa8fc85debff Mon Sep 17 00:00:00 2001 From: JessicaBorja Date: Mon, 10 May 2021 15:26:38 +0200 Subject: [PATCH 07/22] mdpp to cave analysis options, notebook --- mdp_playground/analysis/mdpp_to_cave.py | 59 +- plot_experiments.ipynb | 4197 ++++++++++++++++++++++- rudder_analysis.ipynb | 715 ---- run_experiments.py | 9 +- run_experiments_baselines3.py | 501 +++ test_cave_analysis.py | 33 - 6 files changed, 4728 insertions(+), 786 deletions(-) delete mode 100644 rudder_analysis.ipynb create mode 100644 run_experiments_baselines3.py delete mode 100644 test_cave_analysis.py diff --git a/mdp_playground/analysis/mdpp_to_cave.py b/mdp_playground/analysis/mdpp_to_cave.py index 203a034..6522f14 100644 --- a/mdp_playground/analysis/mdpp_to_cave.py +++ b/mdp_playground/analysis/mdpp_to_cave.py @@ -4,15 +4,15 @@ import json class MDPPToCave(): - def __init__(self, output_dir = "../mdpp_to_cave/"): + def __init__(self): return def _create_configspace_json(self, stats_pd, var_configs): configspace = {"hyperparameters":[], - "conditions": [], - "forbiddens": [], - "python_module_version": "0.4.11", - "json_format_version": 0.1} + "conditions": [], + "forbiddens": [], + "python_module_version": "0.4.11", + "json_format_version": 0.1} for param in var_configs: param_config = {"name": param} var_type = str( type(stats_pd[param].iloc[0]) ) @@ -88,7 +88,7 @@ def _read_stats(self, stats_file): print("\033[1;31mLoading data from a distributed run of experiment configurations. Creating a combined CSV stats file.\033[0;0m") self.join_files(stats_file, '.csv') self.join_files(stats_file, '_eval.csv') - + def to_cave_csv(self, args): #file_path = args.file_path input_folder = "../mdp_files/" @@ -96,7 +96,7 @@ def to_cave_csv(self, args): output_folder = "../to_cave_format/%s"%file_name if not os.path.exists(output_folder): os.makedirs(output_folder) - + ## Read current csvs ## stats_file = os.path.join(input_folder, file_name) with open(stats_file + '.csv') as file_: @@ -145,22 +145,27 @@ def to_bohb_results(self, dir_name, exp_name, output_dir="../cave_output/"): print("Writing bohb to cave output to %s"%(os.path.abspath(output_dir))) os.makedirs(self.output_folder) - #file_path = args.file_path + # file_path = args.file_path output_folder = os.path.join(self.output_folder, exp_name) if not os.path.exists(output_folder): os.makedirs(output_folder) - - ## Read current csvs ## + + # Read current csvs ## stats_file = os.path.join(dir_name, exp_name) + stats_file = os.path.abspath(stats_file) self._read_stats(stats_file) with open(stats_file + '.csv') as file_: col_names = file_.readline().strip().split(', ') - col_names[0] = col_names[0][2:] # to remove '# ' that was written + col_names[0] = col_names[0][2:] # to remove '# ' that was written # print("config_names:", col_names) - stats_pd = pd.read_csv(stats_file + '.csv', skip_blank_lines=True,\ - header=None, names = col_names, comment='#', sep=' ') + stats_pd = pd.read_csv(stats_file + '.csv', + skip_blank_lines=True, + header=None, + names=col_names, + comment='#', + sep=' ') remove_names = ["training_iteration", "algorithm", "seed"] - + parameters = col_names[:-3].copy()#All paramaters tracked in run for x in col_names: for name in remove_names: @@ -244,16 +249,16 @@ def to_bohb_results(self, dir_name, exp_name, output_dir="../cave_output/"): if __name__ == "__main__": - dir_name = '../../../mdp_files/' + dir_name = '../mdp_files/' exp_name = 'dqn_seq_del' from cave.cavefacade import CAVE import os # The converted mdpp csvs will be stored in output_dir - output_dir = "../../../mdpp_to_cave" + output_dir = "../mdpp_to_cave" mdpp_file = os.path.join(dir_name, exp_name) - mdpp_cave = MDPPToCave(output_dir) - cave_input_file = mdpp_cave.to_bohb_results(dir_name, exp_name) + mdpp_cave = MDPPToCave() + cave_input_file = mdpp_cave.to_bohb_results(dir_name, exp_name, output_dir) # cave_input_file = "../../../mdpp_to_cave/dqn_seq_del" @@ -272,9 +277,19 @@ def to_bohb_results(self, dir_name, exp_name, output_dir="../cave_output/"): # Common analysis cave.performance_table() cave.local_parameter_importance() - - # fanova can only be used with more - # more than 1 meta-feature - cave.cave_fanova() + cave.cave_fanova() # can only be used with more than 1 meta-feature # Other analysis + # cave.parallel_coordinates() + # cave.cost_over_time() + # cave.algorithm_footprints() + # cave.pimp_comparison_table() + # cave.cave_ablation() + # cave.pimp_forward_selection() + # cave.feature_importance() + # cave.configurator_footprint() + # cave.algorithm_footprints() + # cave.plot_ecdf() + # cave.plot_scatter() + # cave.compare_default_incumbent() + # cave.overview_table() \ No newline at end of file diff --git a/plot_experiments.ipynb b/plot_experiments.ipynb index 16c17ca..0d17c91 100644 --- a/plot_experiments.ipynb +++ b/plot_experiments.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -15,7 +15,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 6, "metadata": { "scrolled": true }, @@ -24,9 +24,28 @@ "name": "stdout", "output_type": "stream", "text": [ - "Loading data from a distributed run of experiment configurations. Creating a combined CSV stats file.\n", - "51 files were combined into 1 for file:/mnt/484A4CAB4A4C9798/GoogleDrive/Maestria-Drive/HiWi/mdp_files/baselines/a3c_lstm_del//a3c_lstm_del_n.csv\n", - "50 files were combined into 1 for file:/mnt/484A4CAB4A4C9798/GoogleDrive/Maestria-Drive/HiWi/mdp_files/baselines/a3c_lstm_del//a3c_lstm_del_n_eval.csv\n", + "Loading data from a sequential run/already combined runs of experiment configurations.\n", + "Training stats read (rows, columns): (40000, 15)\n", + "train stats shape: (1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 10, 3)\n", + "train_aucs.shape: (1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 10, 3)\n", + "eval stats shape: (1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 10, 3)\n", + "eval_aucs.shape: (1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 10, 3)\n", + "Dimension varied: sequence_length . The values it took: ['1', '2', '3', '4'] . Number of values it took: 4 . Index in loaded data: 4\n", + "Loading data from a sequential run/already combined runs of experiment configurations.\n", + "Training stats read (rows, columns): (40000, 15)\n", + "train stats shape: (1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 10, 3)\n", + "train_aucs.shape: (1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 10, 3)\n", + "eval stats shape: (1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 10, 3)\n", + "eval_aucs.shape: (1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 10, 3)\n", + "Dimension varied: sequence_length . The values it took: ['1', '2', '3', '4'] . Number of values it took: 4 . Index in loaded data: 4\n", + "Loading data from a sequential run/already combined runs of experiment configurations.\n", + "Training stats read (rows, columns): (50000, 15)\n", + "train stats shape: (1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 10, 3)\n", + "train_aucs.shape: (1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 10, 3)\n", + "eval stats shape: (1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 10, 3)\n", + "eval_aucs.shape: (1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 10, 3)\n", + "Dimension varied: delay . The values it took: ['0', '1', '2', '4', '8'] . Number of values it took: 5 . Index in loaded data: 3\n", + "Loading data from a sequential run/already combined runs of experiment configurations.\n", "Training stats read (rows, columns): (50000, 15)\n", "train stats shape: (1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 10, 3)\n", "train_aucs.shape: (1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 10, 3)\n", @@ -48,9 +67,9 @@ "# Set dir_name to the location where the CSV files from running an experiment were saved\n", "files_dir = \"/mnt/484A4CAB4A4C9798/GoogleDrive/Maestria-Drive/HiWi/mdp_files/baselines\"\n", "experiments = {\n", - "# \"a3c_seq\" : \"%s/a3c_seq/\"%files_dir,\n", - "# \"a3c_lstm_seq\" : \"%s/a3c_lstm_seq/\"%files_dir,\n", - "# \"a3c_del\" : \"%s/a3c_del/\"%files_dir,\n", + " \"a3c_seq\" : \"%s/a3c_seq/\"%files_dir,\n", + " \"a3c_lstm_seq\" : \"%s/a3c_lstm_seq/\"%files_dir,\n", + " \"a3c_del\" : \"%s/a3c_del/\"%files_dir,\n", " \"a3c_lstm_del\" : \"%s/a3c_lstm_del/\"%files_dir,\n", "}\n", "\n", @@ -403,9 +422,4146 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[1;31mLoading data from a sequential run/already combined runs of experiment configurations.\u001b[0;0m\n", + "../mdpp_to_cave/a3c_seq\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + "\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "
\n", + "
\n", + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
DefaultIncumbent
Quality-26.43-42.26
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/pimp/evaluator/local_parameter_importance.py:268: RuntimeWarning: invalid value encountered in double_scalars\n", + " overall_var_per_tree = {p : [t / sum_var_per_tree[idx] for idx, t in enumerate(trees)] for p, trees in\n", + "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/pimp/evaluator/local_parameter_importance.py:402: UserWarning: Attempted to set non-positive top ylim on a log-scaled axis.\n", + "Invalid limit will be ignored.\n", + " ax1.set_ylim([min_y * 0.95, max_y])\n" + ] + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "/* global mpl */\n", + "window.mpl = {};\n", + "\n", + "mpl.get_websocket_type = function () {\n", + " if (typeof WebSocket !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof MozWebSocket !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert(\n", + " 'Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.'\n", + " );\n", + " }\n", + "};\n", + "\n", + "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = this.ws.binaryType !== undefined;\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById('mpl-warnings');\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent =\n", + " 'This browser does not support binary websocket messages. ' +\n", + " 'Performance may be slow.';\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = document.createElement('div');\n", + " this.root.setAttribute('style', 'display: inline-block');\n", + " this._root_extra_style(this.root);\n", + "\n", + " parent_element.appendChild(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message('supports_binary', { value: fig.supports_binary });\n", + " fig.send_message('send_image_mode', {});\n", + " if (fig.ratio !== 1) {\n", + " fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n", + " }\n", + " fig.send_message('refresh', {});\n", + " };\n", + "\n", + " this.imageObj.onload = function () {\n", + " if (fig.image_mode === 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function () {\n", + " fig.ws.close();\n", + " };\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "};\n", + "\n", + "mpl.figure.prototype._init_header = function () {\n", + " var titlebar = document.createElement('div');\n", + " titlebar.classList =\n", + " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", + " var titletext = document.createElement('div');\n", + " titletext.classList = 'ui-dialog-title';\n", + " titletext.setAttribute(\n", + " 'style',\n", + " 'width: 100%; text-align: center; padding: 3px;'\n", + " );\n", + " titlebar.appendChild(titletext);\n", + " this.root.appendChild(titlebar);\n", + " this.header = titletext;\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._init_canvas = function () {\n", + " var fig = this;\n", + "\n", + " var canvas_div = (this.canvas_div = document.createElement('div'));\n", + " canvas_div.setAttribute(\n", + " 'style',\n", + " 'border: 1px solid #ddd;' +\n", + " 'box-sizing: content-box;' +\n", + " 'clear: both;' +\n", + " 'min-height: 1px;' +\n", + " 'min-width: 1px;' +\n", + " 'outline: 0;' +\n", + " 'overflow: hidden;' +\n", + " 'position: relative;' +\n", + " 'resize: both;'\n", + " );\n", + "\n", + " function on_keyboard_event_closure(name) {\n", + " return function (event) {\n", + " return fig.key_event(event, name);\n", + " };\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'keydown',\n", + " on_keyboard_event_closure('key_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'keyup',\n", + " on_keyboard_event_closure('key_release')\n", + " );\n", + "\n", + " this._canvas_extra_style(canvas_div);\n", + " this.root.appendChild(canvas_div);\n", + "\n", + " var canvas = (this.canvas = document.createElement('canvas'));\n", + " canvas.classList.add('mpl-canvas');\n", + " canvas.setAttribute('style', 'box-sizing: content-box;');\n", + "\n", + " this.context = canvas.getContext('2d');\n", + "\n", + " var backingStore =\n", + " this.context.backingStorePixelRatio ||\n", + " this.context.webkitBackingStorePixelRatio ||\n", + " this.context.mozBackingStorePixelRatio ||\n", + " this.context.msBackingStorePixelRatio ||\n", + " this.context.oBackingStorePixelRatio ||\n", + " this.context.backingStorePixelRatio ||\n", + " 1;\n", + "\n", + " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", + " 'canvas'\n", + " ));\n", + " rubberband_canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n", + " );\n", + "\n", + " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", + " if (this.ResizeObserver === undefined) {\n", + " if (window.ResizeObserver !== undefined) {\n", + " this.ResizeObserver = window.ResizeObserver;\n", + " } else {\n", + " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", + " this.ResizeObserver = obs.ResizeObserver;\n", + " }\n", + " }\n", + "\n", + " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", + " var nentries = entries.length;\n", + " for (var i = 0; i < nentries; i++) {\n", + " var entry = entries[i];\n", + " var width, height;\n", + " if (entry.contentBoxSize) {\n", + " if (entry.contentBoxSize instanceof Array) {\n", + " // Chrome 84 implements new version of spec.\n", + " width = entry.contentBoxSize[0].inlineSize;\n", + " height = entry.contentBoxSize[0].blockSize;\n", + " } else {\n", + " // Firefox implements old version of spec.\n", + " width = entry.contentBoxSize.inlineSize;\n", + " height = entry.contentBoxSize.blockSize;\n", + " }\n", + " } else {\n", + " // Chrome <84 implements even older version of spec.\n", + " width = entry.contentRect.width;\n", + " height = entry.contentRect.height;\n", + " }\n", + "\n", + " // Keep the size of the canvas and rubber band canvas in sync with\n", + " // the canvas container.\n", + " if (entry.devicePixelContentBoxSize) {\n", + " // Chrome 84 implements new version of spec.\n", + " canvas.setAttribute(\n", + " 'width',\n", + " entry.devicePixelContentBoxSize[0].inlineSize\n", + " );\n", + " canvas.setAttribute(\n", + " 'height',\n", + " entry.devicePixelContentBoxSize[0].blockSize\n", + " );\n", + " } else {\n", + " canvas.setAttribute('width', width * fig.ratio);\n", + " canvas.setAttribute('height', height * fig.ratio);\n", + " }\n", + " canvas.setAttribute(\n", + " 'style',\n", + " 'width: ' + width + 'px; height: ' + height + 'px;'\n", + " );\n", + "\n", + " rubberband_canvas.setAttribute('width', width);\n", + " rubberband_canvas.setAttribute('height', height);\n", + "\n", + " // And update the size in Python. We ignore the initial 0/0 size\n", + " // that occurs as the element is placed into the DOM, which should\n", + " // otherwise not happen due to the minimum size styling.\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", + " fig.request_resize(width, height);\n", + " }\n", + " }\n", + " });\n", + " this.resizeObserverInstance.observe(canvas_div);\n", + "\n", + " function on_mouse_event_closure(name) {\n", + " return function (event) {\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " }\n", + "\n", + " rubberband_canvas.addEventListener(\n", + " 'mousedown',\n", + " on_mouse_event_closure('button_press')\n", + " );\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseup',\n", + " on_mouse_event_closure('button_release')\n", + " );\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband_canvas.addEventListener(\n", + " 'mousemove',\n", + " on_mouse_event_closure('motion_notify')\n", + " );\n", + "\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseenter',\n", + " on_mouse_event_closure('figure_enter')\n", + " );\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseleave',\n", + " on_mouse_event_closure('figure_leave')\n", + " );\n", + "\n", + " canvas_div.addEventListener('wheel', function (event) {\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " on_mouse_event_closure('scroll')(event);\n", + " });\n", + "\n", + " canvas_div.appendChild(canvas);\n", + " canvas_div.appendChild(rubberband_canvas);\n", + "\n", + " this.rubberband_context = rubberband_canvas.getContext('2d');\n", + " this.rubberband_context.strokeStyle = '#000000';\n", + "\n", + " this._resize_canvas = function (width, height, forward) {\n", + " if (forward) {\n", + " canvas_div.style.width = width + 'px';\n", + " canvas_div.style.height = height + 'px';\n", + " }\n", + " };\n", + "\n", + " // Disable right mouse context menu.\n", + " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n", + " event.preventDefault();\n", + " return false;\n", + " });\n", + "\n", + " function set_focus() {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'mpl-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " continue;\n", + " }\n", + "\n", + " var button = (fig.buttons[name] = document.createElement('button'));\n", + " button.classList = 'mpl-widget';\n", + " button.setAttribute('role', 'button');\n", + " button.setAttribute('aria-disabled', 'false');\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + "\n", + " var icon_img = document.createElement('img');\n", + " icon_img.src = '_images/' + image + '.png';\n", + " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", + " icon_img.alt = tooltip;\n", + " button.appendChild(icon_img);\n", + "\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " var fmt_picker = document.createElement('select');\n", + " fmt_picker.classList = 'mpl-widget';\n", + " toolbar.appendChild(fmt_picker);\n", + " this.format_dropdown = fmt_picker;\n", + "\n", + " for (var ind in mpl.extensions) {\n", + " var fmt = mpl.extensions[ind];\n", + " var option = document.createElement('option');\n", + " option.selected = fmt === mpl.default_extension;\n", + " option.innerHTML = fmt;\n", + " fmt_picker.appendChild(option);\n", + " }\n", + "\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "};\n", + "\n", + "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", + " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", + " // which will in turn request a refresh of the image.\n", + " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", + "};\n", + "\n", + "mpl.figure.prototype.send_message = function (type, properties) {\n", + " properties['type'] = type;\n", + " properties['figure_id'] = this.id;\n", + " this.ws.send(JSON.stringify(properties));\n", + "};\n", + "\n", + "mpl.figure.prototype.send_draw_message = function () {\n", + " if (!this.waiting) {\n", + " this.waiting = true;\n", + " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " var format_dropdown = fig.format_dropdown;\n", + " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", + " fig.ondownload(fig, format);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", + " var size = msg['size'];\n", + " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", + " fig._resize_canvas(size[0], size[1], msg['forward']);\n", + " fig.send_message('refresh', {});\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", + " var x0 = msg['x0'] / fig.ratio;\n", + " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", + " var x1 = msg['x1'] / fig.ratio;\n", + " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", + " x0 = Math.floor(x0) + 0.5;\n", + " y0 = Math.floor(y0) + 0.5;\n", + " x1 = Math.floor(x1) + 0.5;\n", + " y1 = Math.floor(y1) + 0.5;\n", + " var min_x = Math.min(x0, x1);\n", + " var min_y = Math.min(y0, y1);\n", + " var width = Math.abs(x1 - x0);\n", + " var height = Math.abs(y1 - y0);\n", + "\n", + " fig.rubberband_context.clearRect(\n", + " 0,\n", + " 0,\n", + " fig.canvas.width / fig.ratio,\n", + " fig.canvas.height / fig.ratio\n", + " );\n", + "\n", + " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", + " // Updates the figure title.\n", + " fig.header.textContent = msg['label'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", + " var cursor = msg['cursor'];\n", + " switch (cursor) {\n", + " case 0:\n", + " cursor = 'pointer';\n", + " break;\n", + " case 1:\n", + " cursor = 'default';\n", + " break;\n", + " case 2:\n", + " cursor = 'crosshair';\n", + " break;\n", + " case 3:\n", + " cursor = 'move';\n", + " break;\n", + " }\n", + " fig.rubberband_canvas.style.cursor = cursor;\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_message = function (fig, msg) {\n", + " fig.message.textContent = msg['message'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", + " // Request the server to send over a new figure.\n", + " fig.send_draw_message();\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", + " fig.image_mode = msg['mode'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", + " for (var key in msg) {\n", + " if (!(key in fig.buttons)) {\n", + " continue;\n", + " }\n", + " fig.buttons[key].disabled = !msg[key];\n", + " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", + " if (msg['mode'] === 'PAN') {\n", + " fig.buttons['Pan'].classList.add('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " } else if (msg['mode'] === 'ZOOM') {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.add('active');\n", + " } else {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Called whenever the canvas gets updated.\n", + " this.send_message('ack', {});\n", + "};\n", + "\n", + "// A function to construct a web socket function for onmessage handling.\n", + "// Called in the figure constructor.\n", + "mpl.figure.prototype._make_on_message_function = function (fig) {\n", + " return function socket_on_message(evt) {\n", + " if (evt.data instanceof Blob) {\n", + " /* FIXME: We get \"Resource interpreted as Image but\n", + " * transferred with MIME type text/plain:\" errors on\n", + " * Chrome. But how to set the MIME type? It doesn't seem\n", + " * to be part of the websocket stream */\n", + " evt.data.type = 'image/png';\n", + "\n", + " /* Free the memory for the previous frames */\n", + " if (fig.imageObj.src) {\n", + " (window.URL || window.webkitURL).revokeObjectURL(\n", + " fig.imageObj.src\n", + " );\n", + " }\n", + "\n", + " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", + " evt.data\n", + " );\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " } else if (\n", + " typeof evt.data === 'string' &&\n", + " evt.data.slice(0, 21) === 'data:image/png;base64'\n", + " ) {\n", + " fig.imageObj.src = evt.data;\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " }\n", + "\n", + " var msg = JSON.parse(evt.data);\n", + " var msg_type = msg['type'];\n", + "\n", + " // Call the \"handle_{type}\" callback, which takes\n", + " // the figure and JSON message as its only arguments.\n", + " try {\n", + " var callback = fig['handle_' + msg_type];\n", + " } catch (e) {\n", + " console.log(\n", + " \"No handler for the '\" + msg_type + \"' message type: \",\n", + " msg\n", + " );\n", + " return;\n", + " }\n", + "\n", + " if (callback) {\n", + " try {\n", + " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", + " callback(fig, msg);\n", + " } catch (e) {\n", + " console.log(\n", + " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", + " e,\n", + " e.stack,\n", + " msg\n", + " );\n", + " }\n", + " }\n", + " };\n", + "};\n", + "\n", + "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", + "mpl.findpos = function (e) {\n", + " //this section is from http://www.quirksmode.org/js/events_properties.html\n", + " var targ;\n", + " if (!e) {\n", + " e = window.event;\n", + " }\n", + " if (e.target) {\n", + " targ = e.target;\n", + " } else if (e.srcElement) {\n", + " targ = e.srcElement;\n", + " }\n", + " if (targ.nodeType === 3) {\n", + " // defeat Safari bug\n", + " targ = targ.parentNode;\n", + " }\n", + "\n", + " // pageX,Y are the mouse positions relative to the document\n", + " var boundingRect = targ.getBoundingClientRect();\n", + " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n", + " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n", + "\n", + " return { x: x, y: y };\n", + "};\n", + "\n", + "/*\n", + " * return a copy of an object with only non-object keys\n", + " * we need this to avoid circular references\n", + " * http://stackoverflow.com/a/24161582/3208463\n", + " */\n", + "function simpleKeys(original) {\n", + " return Object.keys(original).reduce(function (obj, key) {\n", + " if (typeof original[key] !== 'object') {\n", + " obj[key] = original[key];\n", + " }\n", + " return obj;\n", + " }, {});\n", + "}\n", + "\n", + "mpl.figure.prototype.mouse_event = function (event, name) {\n", + " var canvas_pos = mpl.findpos(event);\n", + "\n", + " if (name === 'button_press') {\n", + " this.canvas.focus();\n", + " this.canvas_div.focus();\n", + " }\n", + "\n", + " var x = canvas_pos.x * this.ratio;\n", + " var y = canvas_pos.y * this.ratio;\n", + "\n", + " this.send_message(name, {\n", + " x: x,\n", + " y: y,\n", + " button: event.button,\n", + " step: event.step,\n", + " guiEvent: simpleKeys(event),\n", + " });\n", + "\n", + " /* This prevents the web browser from automatically changing to\n", + " * the text insertion cursor when the button is pressed. We want\n", + " * to control all of the cursor setting manually through the\n", + " * 'cursor' event from matplotlib */\n", + " event.preventDefault();\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", + " // Handle any extra behaviour associated with a key event\n", + "};\n", + "\n", + "mpl.figure.prototype.key_event = function (event, name) {\n", + " // Prevent repeat events\n", + " if (name === 'key_press') {\n", + " if (event.which === this._key) {\n", + " return;\n", + " } else {\n", + " this._key = event.which;\n", + " }\n", + " }\n", + " if (name === 'key_release') {\n", + " this._key = null;\n", + " }\n", + "\n", + " var value = '';\n", + " if (event.ctrlKey && event.which !== 17) {\n", + " value += 'ctrl+';\n", + " }\n", + " if (event.altKey && event.which !== 18) {\n", + " value += 'alt+';\n", + " }\n", + " if (event.shiftKey && event.which !== 16) {\n", + " value += 'shift+';\n", + " }\n", + "\n", + " value += 'k';\n", + " value += event.which.toString();\n", + "\n", + " this._key_event_extra(event, name);\n", + "\n", + " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", + " if (name === 'download') {\n", + " this.handle_save(this, null);\n", + " } else {\n", + " this.send_message('toolbar_button', { name: name });\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", + " this.message.textContent = tooltip;\n", + "};\n", + "\n", + "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", + "// prettier-ignore\n", + "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", + "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", + "\n", + "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", + "\n", + "mpl.default_extension = \"png\";/* global mpl */\n", + "\n", + "var comm_websocket_adapter = function (comm) {\n", + " // Create a \"websocket\"-like object which calls the given IPython comm\n", + " // object with the appropriate methods. Currently this is a non binary\n", + " // socket, so there is still some room for performance tuning.\n", + " var ws = {};\n", + "\n", + " ws.close = function () {\n", + " comm.close();\n", + " };\n", + " ws.send = function (m) {\n", + " //console.log('sending', m);\n", + " comm.send(m);\n", + " };\n", + " // Register the callback with on_msg.\n", + " comm.on_msg(function (msg) {\n", + " //console.log('receiving', msg['content']['data'], msg);\n", + " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", + " ws.onmessage(msg['content']['data']);\n", + " });\n", + " return ws;\n", + "};\n", + "\n", + "mpl.mpl_figure_comm = function (comm, msg) {\n", + " // This is the function which gets called when the mpl process\n", + " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", + "\n", + " var id = msg.content.data.id;\n", + " // Get hold of the div created by the display call when the Comm\n", + " // socket was opened in Python.\n", + " var element = document.getElementById(id);\n", + " var ws_proxy = comm_websocket_adapter(comm);\n", + "\n", + " function ondownload(figure, _format) {\n", + " window.open(figure.canvas.toDataURL());\n", + " }\n", + "\n", + " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", + "\n", + " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", + " // web socket which is closed, not our websocket->open comm proxy.\n", + " ws_proxy.onopen();\n", + "\n", + " fig.parent_element = element;\n", + " fig.cell_info = mpl.find_output_cell(\"
\");\n", + " if (!fig.cell_info) {\n", + " console.error('Failed to find cell for figure', id, fig);\n", + " return;\n", + " }\n", + " fig.cell_info[0].output_area.element.on(\n", + " 'cleared',\n", + " { fig: fig },\n", + " fig._remove_fig_handler\n", + " );\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_close = function (fig, msg) {\n", + " var width = fig.canvas.width / fig.ratio;\n", + " fig.cell_info[0].output_area.element.off(\n", + " 'cleared',\n", + " fig._remove_fig_handler\n", + " );\n", + " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", + "\n", + " // Update the output cell to use the data from the current canvas.\n", + " fig.push_to_output();\n", + " var dataURL = fig.canvas.toDataURL();\n", + " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", + " // the notebook keyboard shortcuts fail.\n", + " IPython.keyboard_manager.enable();\n", + " fig.parent_element.innerHTML =\n", + " '';\n", + " fig.close_ws(fig, msg);\n", + "};\n", + "\n", + "mpl.figure.prototype.close_ws = function (fig, msg) {\n", + " fig.send_message('closing', msg);\n", + " // fig.ws.close()\n", + "};\n", + "\n", + "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", + " // Turn the data on the canvas into data in the output cell.\n", + " var width = this.canvas.width / this.ratio;\n", + " var dataURL = this.canvas.toDataURL();\n", + " this.cell_info[1]['text/html'] =\n", + " '';\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Tell IPython that the notebook contents must change.\n", + " IPython.notebook.set_dirty(true);\n", + " this.send_message('ack', {});\n", + " var fig = this;\n", + " // Wait a second, then push the new image to the DOM so\n", + " // that it is saved nicely (might be nice to debounce this).\n", + " setTimeout(function () {\n", + " fig.push_to_output();\n", + " }, 1000);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'btn-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " var button;\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " continue;\n", + " }\n", + "\n", + " button = fig.buttons[name] = document.createElement('button');\n", + " button.classList = 'btn btn-default';\n", + " button.href = '#';\n", + " button.title = name;\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message pull-right';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = document.createElement('div');\n", + " buttongrp.classList = 'btn-group inline pull-right';\n", + " button = document.createElement('button');\n", + " button.classList = 'btn btn-mini btn-primary';\n", + " button.href = '#';\n", + " button.title = 'Stop Interaction';\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', function (_evt) {\n", + " fig.handle_close(fig, {});\n", + " });\n", + " button.addEventListener(\n", + " 'mouseover',\n", + " on_mouseover_closure('Stop Interaction')\n", + " );\n", + " buttongrp.appendChild(button);\n", + " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", + " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", + "};\n", + "\n", + "mpl.figure.prototype._remove_fig_handler = function (event) {\n", + " var fig = event.data.fig;\n", + " if (event.target !== this) {\n", + " // Ignore bubbled events from children.\n", + " return;\n", + " }\n", + " fig.close_ws(fig, {});\n", + "};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (el) {\n", + " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (el) {\n", + " // this is important to make the div 'focusable\n", + " el.setAttribute('tabindex', 0);\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " } else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager) {\n", + " manager = IPython.keyboard_manager;\n", + " }\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which === 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " fig.ondownload(fig, null);\n", + "};\n", + "\n", + "mpl.find_output_cell = function (html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i = 0; i < ncells; i++) {\n", + " var cell = cells[i];\n", + " if (cell.cell_type === 'code') {\n", + " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", + " var data = cell.output_area.outputs[j];\n", + " if (data.data) {\n", + " // IPython >= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] === html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "};\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel !== null) {\n", + " IPython.notebook.kernel.comm_manager.register_target(\n", + " 'matplotlib',\n", + " mpl.mpl_figure_comm\n", + " );\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[1;31mLoading data from a sequential run/already combined runs of experiment configurations.\u001b[0;0m\n", + "../mdpp_to_cave/a3c_lstm_seq\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + "\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "
\n", + "
\n", + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
DefaultIncumbent
Quality-37.31-40.595
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/pimp/evaluator/local_parameter_importance.py:268: RuntimeWarning: invalid value encountered in double_scalars\n", + " overall_var_per_tree = {p : [t / sum_var_per_tree[idx] for idx, t in enumerate(trees)] for p, trees in\n", + "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/pimp/evaluator/local_parameter_importance.py:402: UserWarning: Attempted to set non-positive top ylim on a log-scaled axis.\n", + "Invalid limit will be ignored.\n", + " ax1.set_ylim([min_y * 0.95, max_y])\n" + ] + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "/* global mpl */\n", + "window.mpl = {};\n", + "\n", + "mpl.get_websocket_type = function () {\n", + " if (typeof WebSocket !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof MozWebSocket !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert(\n", + " 'Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.'\n", + " );\n", + " }\n", + "};\n", + "\n", + "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = this.ws.binaryType !== undefined;\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById('mpl-warnings');\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent =\n", + " 'This browser does not support binary websocket messages. ' +\n", + " 'Performance may be slow.';\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = document.createElement('div');\n", + " this.root.setAttribute('style', 'display: inline-block');\n", + " this._root_extra_style(this.root);\n", + "\n", + " parent_element.appendChild(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message('supports_binary', { value: fig.supports_binary });\n", + " fig.send_message('send_image_mode', {});\n", + " if (fig.ratio !== 1) {\n", + " fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n", + " }\n", + " fig.send_message('refresh', {});\n", + " };\n", + "\n", + " this.imageObj.onload = function () {\n", + " if (fig.image_mode === 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function () {\n", + " fig.ws.close();\n", + " };\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "};\n", + "\n", + "mpl.figure.prototype._init_header = function () {\n", + " var titlebar = document.createElement('div');\n", + " titlebar.classList =\n", + " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", + " var titletext = document.createElement('div');\n", + " titletext.classList = 'ui-dialog-title';\n", + " titletext.setAttribute(\n", + " 'style',\n", + " 'width: 100%; text-align: center; padding: 3px;'\n", + " );\n", + " titlebar.appendChild(titletext);\n", + " this.root.appendChild(titlebar);\n", + " this.header = titletext;\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._init_canvas = function () {\n", + " var fig = this;\n", + "\n", + " var canvas_div = (this.canvas_div = document.createElement('div'));\n", + " canvas_div.setAttribute(\n", + " 'style',\n", + " 'border: 1px solid #ddd;' +\n", + " 'box-sizing: content-box;' +\n", + " 'clear: both;' +\n", + " 'min-height: 1px;' +\n", + " 'min-width: 1px;' +\n", + " 'outline: 0;' +\n", + " 'overflow: hidden;' +\n", + " 'position: relative;' +\n", + " 'resize: both;'\n", + " );\n", + "\n", + " function on_keyboard_event_closure(name) {\n", + " return function (event) {\n", + " return fig.key_event(event, name);\n", + " };\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'keydown',\n", + " on_keyboard_event_closure('key_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'keyup',\n", + " on_keyboard_event_closure('key_release')\n", + " );\n", + "\n", + " this._canvas_extra_style(canvas_div);\n", + " this.root.appendChild(canvas_div);\n", + "\n", + " var canvas = (this.canvas = document.createElement('canvas'));\n", + " canvas.classList.add('mpl-canvas');\n", + " canvas.setAttribute('style', 'box-sizing: content-box;');\n", + "\n", + " this.context = canvas.getContext('2d');\n", + "\n", + " var backingStore =\n", + " this.context.backingStorePixelRatio ||\n", + " this.context.webkitBackingStorePixelRatio ||\n", + " this.context.mozBackingStorePixelRatio ||\n", + " this.context.msBackingStorePixelRatio ||\n", + " this.context.oBackingStorePixelRatio ||\n", + " this.context.backingStorePixelRatio ||\n", + " 1;\n", + "\n", + " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", + " 'canvas'\n", + " ));\n", + " rubberband_canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n", + " );\n", + "\n", + " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", + " if (this.ResizeObserver === undefined) {\n", + " if (window.ResizeObserver !== undefined) {\n", + " this.ResizeObserver = window.ResizeObserver;\n", + " } else {\n", + " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", + " this.ResizeObserver = obs.ResizeObserver;\n", + " }\n", + " }\n", + "\n", + " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", + " var nentries = entries.length;\n", + " for (var i = 0; i < nentries; i++) {\n", + " var entry = entries[i];\n", + " var width, height;\n", + " if (entry.contentBoxSize) {\n", + " if (entry.contentBoxSize instanceof Array) {\n", + " // Chrome 84 implements new version of spec.\n", + " width = entry.contentBoxSize[0].inlineSize;\n", + " height = entry.contentBoxSize[0].blockSize;\n", + " } else {\n", + " // Firefox implements old version of spec.\n", + " width = entry.contentBoxSize.inlineSize;\n", + " height = entry.contentBoxSize.blockSize;\n", + " }\n", + " } else {\n", + " // Chrome <84 implements even older version of spec.\n", + " width = entry.contentRect.width;\n", + " height = entry.contentRect.height;\n", + " }\n", + "\n", + " // Keep the size of the canvas and rubber band canvas in sync with\n", + " // the canvas container.\n", + " if (entry.devicePixelContentBoxSize) {\n", + " // Chrome 84 implements new version of spec.\n", + " canvas.setAttribute(\n", + " 'width',\n", + " entry.devicePixelContentBoxSize[0].inlineSize\n", + " );\n", + " canvas.setAttribute(\n", + " 'height',\n", + " entry.devicePixelContentBoxSize[0].blockSize\n", + " );\n", + " } else {\n", + " canvas.setAttribute('width', width * fig.ratio);\n", + " canvas.setAttribute('height', height * fig.ratio);\n", + " }\n", + " canvas.setAttribute(\n", + " 'style',\n", + " 'width: ' + width + 'px; height: ' + height + 'px;'\n", + " );\n", + "\n", + " rubberband_canvas.setAttribute('width', width);\n", + " rubberband_canvas.setAttribute('height', height);\n", + "\n", + " // And update the size in Python. We ignore the initial 0/0 size\n", + " // that occurs as the element is placed into the DOM, which should\n", + " // otherwise not happen due to the minimum size styling.\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", + " fig.request_resize(width, height);\n", + " }\n", + " }\n", + " });\n", + " this.resizeObserverInstance.observe(canvas_div);\n", + "\n", + " function on_mouse_event_closure(name) {\n", + " return function (event) {\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " }\n", + "\n", + " rubberband_canvas.addEventListener(\n", + " 'mousedown',\n", + " on_mouse_event_closure('button_press')\n", + " );\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseup',\n", + " on_mouse_event_closure('button_release')\n", + " );\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband_canvas.addEventListener(\n", + " 'mousemove',\n", + " on_mouse_event_closure('motion_notify')\n", + " );\n", + "\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseenter',\n", + " on_mouse_event_closure('figure_enter')\n", + " );\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseleave',\n", + " on_mouse_event_closure('figure_leave')\n", + " );\n", + "\n", + " canvas_div.addEventListener('wheel', function (event) {\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " on_mouse_event_closure('scroll')(event);\n", + " });\n", + "\n", + " canvas_div.appendChild(canvas);\n", + " canvas_div.appendChild(rubberband_canvas);\n", + "\n", + " this.rubberband_context = rubberband_canvas.getContext('2d');\n", + " this.rubberband_context.strokeStyle = '#000000';\n", + "\n", + " this._resize_canvas = function (width, height, forward) {\n", + " if (forward) {\n", + " canvas_div.style.width = width + 'px';\n", + " canvas_div.style.height = height + 'px';\n", + " }\n", + " };\n", + "\n", + " // Disable right mouse context menu.\n", + " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n", + " event.preventDefault();\n", + " return false;\n", + " });\n", + "\n", + " function set_focus() {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'mpl-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " continue;\n", + " }\n", + "\n", + " var button = (fig.buttons[name] = document.createElement('button'));\n", + " button.classList = 'mpl-widget';\n", + " button.setAttribute('role', 'button');\n", + " button.setAttribute('aria-disabled', 'false');\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + "\n", + " var icon_img = document.createElement('img');\n", + " icon_img.src = '_images/' + image + '.png';\n", + " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", + " icon_img.alt = tooltip;\n", + " button.appendChild(icon_img);\n", + "\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " var fmt_picker = document.createElement('select');\n", + " fmt_picker.classList = 'mpl-widget';\n", + " toolbar.appendChild(fmt_picker);\n", + " this.format_dropdown = fmt_picker;\n", + "\n", + " for (var ind in mpl.extensions) {\n", + " var fmt = mpl.extensions[ind];\n", + " var option = document.createElement('option');\n", + " option.selected = fmt === mpl.default_extension;\n", + " option.innerHTML = fmt;\n", + " fmt_picker.appendChild(option);\n", + " }\n", + "\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "};\n", + "\n", + "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", + " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", + " // which will in turn request a refresh of the image.\n", + " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", + "};\n", + "\n", + "mpl.figure.prototype.send_message = function (type, properties) {\n", + " properties['type'] = type;\n", + " properties['figure_id'] = this.id;\n", + " this.ws.send(JSON.stringify(properties));\n", + "};\n", + "\n", + "mpl.figure.prototype.send_draw_message = function () {\n", + " if (!this.waiting) {\n", + " this.waiting = true;\n", + " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " var format_dropdown = fig.format_dropdown;\n", + " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", + " fig.ondownload(fig, format);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", + " var size = msg['size'];\n", + " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", + " fig._resize_canvas(size[0], size[1], msg['forward']);\n", + " fig.send_message('refresh', {});\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", + " var x0 = msg['x0'] / fig.ratio;\n", + " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", + " var x1 = msg['x1'] / fig.ratio;\n", + " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", + " x0 = Math.floor(x0) + 0.5;\n", + " y0 = Math.floor(y0) + 0.5;\n", + " x1 = Math.floor(x1) + 0.5;\n", + " y1 = Math.floor(y1) + 0.5;\n", + " var min_x = Math.min(x0, x1);\n", + " var min_y = Math.min(y0, y1);\n", + " var width = Math.abs(x1 - x0);\n", + " var height = Math.abs(y1 - y0);\n", + "\n", + " fig.rubberband_context.clearRect(\n", + " 0,\n", + " 0,\n", + " fig.canvas.width / fig.ratio,\n", + " fig.canvas.height / fig.ratio\n", + " );\n", + "\n", + " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", + " // Updates the figure title.\n", + " fig.header.textContent = msg['label'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", + " var cursor = msg['cursor'];\n", + " switch (cursor) {\n", + " case 0:\n", + " cursor = 'pointer';\n", + " break;\n", + " case 1:\n", + " cursor = 'default';\n", + " break;\n", + " case 2:\n", + " cursor = 'crosshair';\n", + " break;\n", + " case 3:\n", + " cursor = 'move';\n", + " break;\n", + " }\n", + " fig.rubberband_canvas.style.cursor = cursor;\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_message = function (fig, msg) {\n", + " fig.message.textContent = msg['message'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", + " // Request the server to send over a new figure.\n", + " fig.send_draw_message();\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", + " fig.image_mode = msg['mode'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", + " for (var key in msg) {\n", + " if (!(key in fig.buttons)) {\n", + " continue;\n", + " }\n", + " fig.buttons[key].disabled = !msg[key];\n", + " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", + " if (msg['mode'] === 'PAN') {\n", + " fig.buttons['Pan'].classList.add('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " } else if (msg['mode'] === 'ZOOM') {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.add('active');\n", + " } else {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Called whenever the canvas gets updated.\n", + " this.send_message('ack', {});\n", + "};\n", + "\n", + "// A function to construct a web socket function for onmessage handling.\n", + "// Called in the figure constructor.\n", + "mpl.figure.prototype._make_on_message_function = function (fig) {\n", + " return function socket_on_message(evt) {\n", + " if (evt.data instanceof Blob) {\n", + " /* FIXME: We get \"Resource interpreted as Image but\n", + " * transferred with MIME type text/plain:\" errors on\n", + " * Chrome. But how to set the MIME type? It doesn't seem\n", + " * to be part of the websocket stream */\n", + " evt.data.type = 'image/png';\n", + "\n", + " /* Free the memory for the previous frames */\n", + " if (fig.imageObj.src) {\n", + " (window.URL || window.webkitURL).revokeObjectURL(\n", + " fig.imageObj.src\n", + " );\n", + " }\n", + "\n", + " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", + " evt.data\n", + " );\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " } else if (\n", + " typeof evt.data === 'string' &&\n", + " evt.data.slice(0, 21) === 'data:image/png;base64'\n", + " ) {\n", + " fig.imageObj.src = evt.data;\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " }\n", + "\n", + " var msg = JSON.parse(evt.data);\n", + " var msg_type = msg['type'];\n", + "\n", + " // Call the \"handle_{type}\" callback, which takes\n", + " // the figure and JSON message as its only arguments.\n", + " try {\n", + " var callback = fig['handle_' + msg_type];\n", + " } catch (e) {\n", + " console.log(\n", + " \"No handler for the '\" + msg_type + \"' message type: \",\n", + " msg\n", + " );\n", + " return;\n", + " }\n", + "\n", + " if (callback) {\n", + " try {\n", + " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", + " callback(fig, msg);\n", + " } catch (e) {\n", + " console.log(\n", + " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", + " e,\n", + " e.stack,\n", + " msg\n", + " );\n", + " }\n", + " }\n", + " };\n", + "};\n", + "\n", + "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", + "mpl.findpos = function (e) {\n", + " //this section is from http://www.quirksmode.org/js/events_properties.html\n", + " var targ;\n", + " if (!e) {\n", + " e = window.event;\n", + " }\n", + " if (e.target) {\n", + " targ = e.target;\n", + " } else if (e.srcElement) {\n", + " targ = e.srcElement;\n", + " }\n", + " if (targ.nodeType === 3) {\n", + " // defeat Safari bug\n", + " targ = targ.parentNode;\n", + " }\n", + "\n", + " // pageX,Y are the mouse positions relative to the document\n", + " var boundingRect = targ.getBoundingClientRect();\n", + " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n", + " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n", + "\n", + " return { x: x, y: y };\n", + "};\n", + "\n", + "/*\n", + " * return a copy of an object with only non-object keys\n", + " * we need this to avoid circular references\n", + " * http://stackoverflow.com/a/24161582/3208463\n", + " */\n", + "function simpleKeys(original) {\n", + " return Object.keys(original).reduce(function (obj, key) {\n", + " if (typeof original[key] !== 'object') {\n", + " obj[key] = original[key];\n", + " }\n", + " return obj;\n", + " }, {});\n", + "}\n", + "\n", + "mpl.figure.prototype.mouse_event = function (event, name) {\n", + " var canvas_pos = mpl.findpos(event);\n", + "\n", + " if (name === 'button_press') {\n", + " this.canvas.focus();\n", + " this.canvas_div.focus();\n", + " }\n", + "\n", + " var x = canvas_pos.x * this.ratio;\n", + " var y = canvas_pos.y * this.ratio;\n", + "\n", + " this.send_message(name, {\n", + " x: x,\n", + " y: y,\n", + " button: event.button,\n", + " step: event.step,\n", + " guiEvent: simpleKeys(event),\n", + " });\n", + "\n", + " /* This prevents the web browser from automatically changing to\n", + " * the text insertion cursor when the button is pressed. We want\n", + " * to control all of the cursor setting manually through the\n", + " * 'cursor' event from matplotlib */\n", + " event.preventDefault();\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", + " // Handle any extra behaviour associated with a key event\n", + "};\n", + "\n", + "mpl.figure.prototype.key_event = function (event, name) {\n", + " // Prevent repeat events\n", + " if (name === 'key_press') {\n", + " if (event.which === this._key) {\n", + " return;\n", + " } else {\n", + " this._key = event.which;\n", + " }\n", + " }\n", + " if (name === 'key_release') {\n", + " this._key = null;\n", + " }\n", + "\n", + " var value = '';\n", + " if (event.ctrlKey && event.which !== 17) {\n", + " value += 'ctrl+';\n", + " }\n", + " if (event.altKey && event.which !== 18) {\n", + " value += 'alt+';\n", + " }\n", + " if (event.shiftKey && event.which !== 16) {\n", + " value += 'shift+';\n", + " }\n", + "\n", + " value += 'k';\n", + " value += event.which.toString();\n", + "\n", + " this._key_event_extra(event, name);\n", + "\n", + " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", + " if (name === 'download') {\n", + " this.handle_save(this, null);\n", + " } else {\n", + " this.send_message('toolbar_button', { name: name });\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", + " this.message.textContent = tooltip;\n", + "};\n", + "\n", + "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", + "// prettier-ignore\n", + "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", + "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", + "\n", + "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", + "\n", + "mpl.default_extension = \"png\";/* global mpl */\n", + "\n", + "var comm_websocket_adapter = function (comm) {\n", + " // Create a \"websocket\"-like object which calls the given IPython comm\n", + " // object with the appropriate methods. Currently this is a non binary\n", + " // socket, so there is still some room for performance tuning.\n", + " var ws = {};\n", + "\n", + " ws.close = function () {\n", + " comm.close();\n", + " };\n", + " ws.send = function (m) {\n", + " //console.log('sending', m);\n", + " comm.send(m);\n", + " };\n", + " // Register the callback with on_msg.\n", + " comm.on_msg(function (msg) {\n", + " //console.log('receiving', msg['content']['data'], msg);\n", + " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", + " ws.onmessage(msg['content']['data']);\n", + " });\n", + " return ws;\n", + "};\n", + "\n", + "mpl.mpl_figure_comm = function (comm, msg) {\n", + " // This is the function which gets called when the mpl process\n", + " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", + "\n", + " var id = msg.content.data.id;\n", + " // Get hold of the div created by the display call when the Comm\n", + " // socket was opened in Python.\n", + " var element = document.getElementById(id);\n", + " var ws_proxy = comm_websocket_adapter(comm);\n", + "\n", + " function ondownload(figure, _format) {\n", + " window.open(figure.canvas.toDataURL());\n", + " }\n", + "\n", + " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", + "\n", + " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", + " // web socket which is closed, not our websocket->open comm proxy.\n", + " ws_proxy.onopen();\n", + "\n", + " fig.parent_element = element;\n", + " fig.cell_info = mpl.find_output_cell(\"
\");\n", + " if (!fig.cell_info) {\n", + " console.error('Failed to find cell for figure', id, fig);\n", + " return;\n", + " }\n", + " fig.cell_info[0].output_area.element.on(\n", + " 'cleared',\n", + " { fig: fig },\n", + " fig._remove_fig_handler\n", + " );\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_close = function (fig, msg) {\n", + " var width = fig.canvas.width / fig.ratio;\n", + " fig.cell_info[0].output_area.element.off(\n", + " 'cleared',\n", + " fig._remove_fig_handler\n", + " );\n", + " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", + "\n", + " // Update the output cell to use the data from the current canvas.\n", + " fig.push_to_output();\n", + " var dataURL = fig.canvas.toDataURL();\n", + " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", + " // the notebook keyboard shortcuts fail.\n", + " IPython.keyboard_manager.enable();\n", + " fig.parent_element.innerHTML =\n", + " '';\n", + " fig.close_ws(fig, msg);\n", + "};\n", + "\n", + "mpl.figure.prototype.close_ws = function (fig, msg) {\n", + " fig.send_message('closing', msg);\n", + " // fig.ws.close()\n", + "};\n", + "\n", + "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", + " // Turn the data on the canvas into data in the output cell.\n", + " var width = this.canvas.width / this.ratio;\n", + " var dataURL = this.canvas.toDataURL();\n", + " this.cell_info[1]['text/html'] =\n", + " '';\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Tell IPython that the notebook contents must change.\n", + " IPython.notebook.set_dirty(true);\n", + " this.send_message('ack', {});\n", + " var fig = this;\n", + " // Wait a second, then push the new image to the DOM so\n", + " // that it is saved nicely (might be nice to debounce this).\n", + " setTimeout(function () {\n", + " fig.push_to_output();\n", + " }, 1000);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'btn-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " var button;\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " continue;\n", + " }\n", + "\n", + " button = fig.buttons[name] = document.createElement('button');\n", + " button.classList = 'btn btn-default';\n", + " button.href = '#';\n", + " button.title = name;\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message pull-right';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = document.createElement('div');\n", + " buttongrp.classList = 'btn-group inline pull-right';\n", + " button = document.createElement('button');\n", + " button.classList = 'btn btn-mini btn-primary';\n", + " button.href = '#';\n", + " button.title = 'Stop Interaction';\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', function (_evt) {\n", + " fig.handle_close(fig, {});\n", + " });\n", + " button.addEventListener(\n", + " 'mouseover',\n", + " on_mouseover_closure('Stop Interaction')\n", + " );\n", + " buttongrp.appendChild(button);\n", + " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", + " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", + "};\n", + "\n", + "mpl.figure.prototype._remove_fig_handler = function (event) {\n", + " var fig = event.data.fig;\n", + " if (event.target !== this) {\n", + " // Ignore bubbled events from children.\n", + " return;\n", + " }\n", + " fig.close_ws(fig, {});\n", + "};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (el) {\n", + " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (el) {\n", + " // this is important to make the div 'focusable\n", + " el.setAttribute('tabindex', 0);\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " } else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager) {\n", + " manager = IPython.keyboard_manager;\n", + " }\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which === 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " fig.ondownload(fig, null);\n", + "};\n", + "\n", + "mpl.find_output_cell = function (html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i = 0; i < ncells; i++) {\n", + " var cell = cells[i];\n", + " if (cell.cell_type === 'code') {\n", + " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", + " var data = cell.output_area.outputs[j];\n", + " if (data.data) {\n", + " // IPython >= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] === html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "};\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel !== null) {\n", + " IPython.notebook.kernel.comm_manager.register_target(\n", + " 'matplotlib',\n", + " mpl.mpl_figure_comm\n", + " );\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[1;31mLoading data from a sequential run/already combined runs of experiment configurations.\u001b[0;0m\n", + "../mdpp_to_cave/a3c_del\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + "\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "
\n", + "
\n", + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
DefaultIncumbent
Quality-23.71-41.32
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/pimp/evaluator/local_parameter_importance.py:268: RuntimeWarning: invalid value encountered in double_scalars\n", + " overall_var_per_tree = {p : [t / sum_var_per_tree[idx] for idx, t in enumerate(trees)] for p, trees in\n", + "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/pimp/evaluator/local_parameter_importance.py:402: UserWarning: Attempted to set non-positive top ylim on a log-scaled axis.\n", + "Invalid limit will be ignored.\n", + " ax1.set_ylim([min_y * 0.95, max_y])\n" + ] + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "/* global mpl */\n", + "window.mpl = {};\n", + "\n", + "mpl.get_websocket_type = function () {\n", + " if (typeof WebSocket !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof MozWebSocket !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert(\n", + " 'Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.'\n", + " );\n", + " }\n", + "};\n", + "\n", + "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = this.ws.binaryType !== undefined;\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById('mpl-warnings');\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent =\n", + " 'This browser does not support binary websocket messages. ' +\n", + " 'Performance may be slow.';\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = document.createElement('div');\n", + " this.root.setAttribute('style', 'display: inline-block');\n", + " this._root_extra_style(this.root);\n", + "\n", + " parent_element.appendChild(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message('supports_binary', { value: fig.supports_binary });\n", + " fig.send_message('send_image_mode', {});\n", + " if (fig.ratio !== 1) {\n", + " fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n", + " }\n", + " fig.send_message('refresh', {});\n", + " };\n", + "\n", + " this.imageObj.onload = function () {\n", + " if (fig.image_mode === 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function () {\n", + " fig.ws.close();\n", + " };\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "};\n", + "\n", + "mpl.figure.prototype._init_header = function () {\n", + " var titlebar = document.createElement('div');\n", + " titlebar.classList =\n", + " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", + " var titletext = document.createElement('div');\n", + " titletext.classList = 'ui-dialog-title';\n", + " titletext.setAttribute(\n", + " 'style',\n", + " 'width: 100%; text-align: center; padding: 3px;'\n", + " );\n", + " titlebar.appendChild(titletext);\n", + " this.root.appendChild(titlebar);\n", + " this.header = titletext;\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._init_canvas = function () {\n", + " var fig = this;\n", + "\n", + " var canvas_div = (this.canvas_div = document.createElement('div'));\n", + " canvas_div.setAttribute(\n", + " 'style',\n", + " 'border: 1px solid #ddd;' +\n", + " 'box-sizing: content-box;' +\n", + " 'clear: both;' +\n", + " 'min-height: 1px;' +\n", + " 'min-width: 1px;' +\n", + " 'outline: 0;' +\n", + " 'overflow: hidden;' +\n", + " 'position: relative;' +\n", + " 'resize: both;'\n", + " );\n", + "\n", + " function on_keyboard_event_closure(name) {\n", + " return function (event) {\n", + " return fig.key_event(event, name);\n", + " };\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'keydown',\n", + " on_keyboard_event_closure('key_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'keyup',\n", + " on_keyboard_event_closure('key_release')\n", + " );\n", + "\n", + " this._canvas_extra_style(canvas_div);\n", + " this.root.appendChild(canvas_div);\n", + "\n", + " var canvas = (this.canvas = document.createElement('canvas'));\n", + " canvas.classList.add('mpl-canvas');\n", + " canvas.setAttribute('style', 'box-sizing: content-box;');\n", + "\n", + " this.context = canvas.getContext('2d');\n", + "\n", + " var backingStore =\n", + " this.context.backingStorePixelRatio ||\n", + " this.context.webkitBackingStorePixelRatio ||\n", + " this.context.mozBackingStorePixelRatio ||\n", + " this.context.msBackingStorePixelRatio ||\n", + " this.context.oBackingStorePixelRatio ||\n", + " this.context.backingStorePixelRatio ||\n", + " 1;\n", + "\n", + " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", + " 'canvas'\n", + " ));\n", + " rubberband_canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n", + " );\n", + "\n", + " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", + " if (this.ResizeObserver === undefined) {\n", + " if (window.ResizeObserver !== undefined) {\n", + " this.ResizeObserver = window.ResizeObserver;\n", + " } else {\n", + " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", + " this.ResizeObserver = obs.ResizeObserver;\n", + " }\n", + " }\n", + "\n", + " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", + " var nentries = entries.length;\n", + " for (var i = 0; i < nentries; i++) {\n", + " var entry = entries[i];\n", + " var width, height;\n", + " if (entry.contentBoxSize) {\n", + " if (entry.contentBoxSize instanceof Array) {\n", + " // Chrome 84 implements new version of spec.\n", + " width = entry.contentBoxSize[0].inlineSize;\n", + " height = entry.contentBoxSize[0].blockSize;\n", + " } else {\n", + " // Firefox implements old version of spec.\n", + " width = entry.contentBoxSize.inlineSize;\n", + " height = entry.contentBoxSize.blockSize;\n", + " }\n", + " } else {\n", + " // Chrome <84 implements even older version of spec.\n", + " width = entry.contentRect.width;\n", + " height = entry.contentRect.height;\n", + " }\n", + "\n", + " // Keep the size of the canvas and rubber band canvas in sync with\n", + " // the canvas container.\n", + " if (entry.devicePixelContentBoxSize) {\n", + " // Chrome 84 implements new version of spec.\n", + " canvas.setAttribute(\n", + " 'width',\n", + " entry.devicePixelContentBoxSize[0].inlineSize\n", + " );\n", + " canvas.setAttribute(\n", + " 'height',\n", + " entry.devicePixelContentBoxSize[0].blockSize\n", + " );\n", + " } else {\n", + " canvas.setAttribute('width', width * fig.ratio);\n", + " canvas.setAttribute('height', height * fig.ratio);\n", + " }\n", + " canvas.setAttribute(\n", + " 'style',\n", + " 'width: ' + width + 'px; height: ' + height + 'px;'\n", + " );\n", + "\n", + " rubberband_canvas.setAttribute('width', width);\n", + " rubberband_canvas.setAttribute('height', height);\n", + "\n", + " // And update the size in Python. We ignore the initial 0/0 size\n", + " // that occurs as the element is placed into the DOM, which should\n", + " // otherwise not happen due to the minimum size styling.\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", + " fig.request_resize(width, height);\n", + " }\n", + " }\n", + " });\n", + " this.resizeObserverInstance.observe(canvas_div);\n", + "\n", + " function on_mouse_event_closure(name) {\n", + " return function (event) {\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " }\n", + "\n", + " rubberband_canvas.addEventListener(\n", + " 'mousedown',\n", + " on_mouse_event_closure('button_press')\n", + " );\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseup',\n", + " on_mouse_event_closure('button_release')\n", + " );\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband_canvas.addEventListener(\n", + " 'mousemove',\n", + " on_mouse_event_closure('motion_notify')\n", + " );\n", + "\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseenter',\n", + " on_mouse_event_closure('figure_enter')\n", + " );\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseleave',\n", + " on_mouse_event_closure('figure_leave')\n", + " );\n", + "\n", + " canvas_div.addEventListener('wheel', function (event) {\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " on_mouse_event_closure('scroll')(event);\n", + " });\n", + "\n", + " canvas_div.appendChild(canvas);\n", + " canvas_div.appendChild(rubberband_canvas);\n", + "\n", + " this.rubberband_context = rubberband_canvas.getContext('2d');\n", + " this.rubberband_context.strokeStyle = '#000000';\n", + "\n", + " this._resize_canvas = function (width, height, forward) {\n", + " if (forward) {\n", + " canvas_div.style.width = width + 'px';\n", + " canvas_div.style.height = height + 'px';\n", + " }\n", + " };\n", + "\n", + " // Disable right mouse context menu.\n", + " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n", + " event.preventDefault();\n", + " return false;\n", + " });\n", + "\n", + " function set_focus() {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'mpl-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " continue;\n", + " }\n", + "\n", + " var button = (fig.buttons[name] = document.createElement('button'));\n", + " button.classList = 'mpl-widget';\n", + " button.setAttribute('role', 'button');\n", + " button.setAttribute('aria-disabled', 'false');\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + "\n", + " var icon_img = document.createElement('img');\n", + " icon_img.src = '_images/' + image + '.png';\n", + " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", + " icon_img.alt = tooltip;\n", + " button.appendChild(icon_img);\n", + "\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " var fmt_picker = document.createElement('select');\n", + " fmt_picker.classList = 'mpl-widget';\n", + " toolbar.appendChild(fmt_picker);\n", + " this.format_dropdown = fmt_picker;\n", + "\n", + " for (var ind in mpl.extensions) {\n", + " var fmt = mpl.extensions[ind];\n", + " var option = document.createElement('option');\n", + " option.selected = fmt === mpl.default_extension;\n", + " option.innerHTML = fmt;\n", + " fmt_picker.appendChild(option);\n", + " }\n", + "\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "};\n", + "\n", + "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", + " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", + " // which will in turn request a refresh of the image.\n", + " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", + "};\n", + "\n", + "mpl.figure.prototype.send_message = function (type, properties) {\n", + " properties['type'] = type;\n", + " properties['figure_id'] = this.id;\n", + " this.ws.send(JSON.stringify(properties));\n", + "};\n", + "\n", + "mpl.figure.prototype.send_draw_message = function () {\n", + " if (!this.waiting) {\n", + " this.waiting = true;\n", + " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " var format_dropdown = fig.format_dropdown;\n", + " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", + " fig.ondownload(fig, format);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", + " var size = msg['size'];\n", + " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", + " fig._resize_canvas(size[0], size[1], msg['forward']);\n", + " fig.send_message('refresh', {});\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", + " var x0 = msg['x0'] / fig.ratio;\n", + " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", + " var x1 = msg['x1'] / fig.ratio;\n", + " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", + " x0 = Math.floor(x0) + 0.5;\n", + " y0 = Math.floor(y0) + 0.5;\n", + " x1 = Math.floor(x1) + 0.5;\n", + " y1 = Math.floor(y1) + 0.5;\n", + " var min_x = Math.min(x0, x1);\n", + " var min_y = Math.min(y0, y1);\n", + " var width = Math.abs(x1 - x0);\n", + " var height = Math.abs(y1 - y0);\n", + "\n", + " fig.rubberband_context.clearRect(\n", + " 0,\n", + " 0,\n", + " fig.canvas.width / fig.ratio,\n", + " fig.canvas.height / fig.ratio\n", + " );\n", + "\n", + " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", + " // Updates the figure title.\n", + " fig.header.textContent = msg['label'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", + " var cursor = msg['cursor'];\n", + " switch (cursor) {\n", + " case 0:\n", + " cursor = 'pointer';\n", + " break;\n", + " case 1:\n", + " cursor = 'default';\n", + " break;\n", + " case 2:\n", + " cursor = 'crosshair';\n", + " break;\n", + " case 3:\n", + " cursor = 'move';\n", + " break;\n", + " }\n", + " fig.rubberband_canvas.style.cursor = cursor;\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_message = function (fig, msg) {\n", + " fig.message.textContent = msg['message'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", + " // Request the server to send over a new figure.\n", + " fig.send_draw_message();\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", + " fig.image_mode = msg['mode'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", + " for (var key in msg) {\n", + " if (!(key in fig.buttons)) {\n", + " continue;\n", + " }\n", + " fig.buttons[key].disabled = !msg[key];\n", + " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", + " if (msg['mode'] === 'PAN') {\n", + " fig.buttons['Pan'].classList.add('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " } else if (msg['mode'] === 'ZOOM') {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.add('active');\n", + " } else {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Called whenever the canvas gets updated.\n", + " this.send_message('ack', {});\n", + "};\n", + "\n", + "// A function to construct a web socket function for onmessage handling.\n", + "// Called in the figure constructor.\n", + "mpl.figure.prototype._make_on_message_function = function (fig) {\n", + " return function socket_on_message(evt) {\n", + " if (evt.data instanceof Blob) {\n", + " /* FIXME: We get \"Resource interpreted as Image but\n", + " * transferred with MIME type text/plain:\" errors on\n", + " * Chrome. But how to set the MIME type? It doesn't seem\n", + " * to be part of the websocket stream */\n", + " evt.data.type = 'image/png';\n", + "\n", + " /* Free the memory for the previous frames */\n", + " if (fig.imageObj.src) {\n", + " (window.URL || window.webkitURL).revokeObjectURL(\n", + " fig.imageObj.src\n", + " );\n", + " }\n", + "\n", + " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", + " evt.data\n", + " );\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " } else if (\n", + " typeof evt.data === 'string' &&\n", + " evt.data.slice(0, 21) === 'data:image/png;base64'\n", + " ) {\n", + " fig.imageObj.src = evt.data;\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " }\n", + "\n", + " var msg = JSON.parse(evt.data);\n", + " var msg_type = msg['type'];\n", + "\n", + " // Call the \"handle_{type}\" callback, which takes\n", + " // the figure and JSON message as its only arguments.\n", + " try {\n", + " var callback = fig['handle_' + msg_type];\n", + " } catch (e) {\n", + " console.log(\n", + " \"No handler for the '\" + msg_type + \"' message type: \",\n", + " msg\n", + " );\n", + " return;\n", + " }\n", + "\n", + " if (callback) {\n", + " try {\n", + " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", + " callback(fig, msg);\n", + " } catch (e) {\n", + " console.log(\n", + " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", + " e,\n", + " e.stack,\n", + " msg\n", + " );\n", + " }\n", + " }\n", + " };\n", + "};\n", + "\n", + "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", + "mpl.findpos = function (e) {\n", + " //this section is from http://www.quirksmode.org/js/events_properties.html\n", + " var targ;\n", + " if (!e) {\n", + " e = window.event;\n", + " }\n", + " if (e.target) {\n", + " targ = e.target;\n", + " } else if (e.srcElement) {\n", + " targ = e.srcElement;\n", + " }\n", + " if (targ.nodeType === 3) {\n", + " // defeat Safari bug\n", + " targ = targ.parentNode;\n", + " }\n", + "\n", + " // pageX,Y are the mouse positions relative to the document\n", + " var boundingRect = targ.getBoundingClientRect();\n", + " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n", + " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n", + "\n", + " return { x: x, y: y };\n", + "};\n", + "\n", + "/*\n", + " * return a copy of an object with only non-object keys\n", + " * we need this to avoid circular references\n", + " * http://stackoverflow.com/a/24161582/3208463\n", + " */\n", + "function simpleKeys(original) {\n", + " return Object.keys(original).reduce(function (obj, key) {\n", + " if (typeof original[key] !== 'object') {\n", + " obj[key] = original[key];\n", + " }\n", + " return obj;\n", + " }, {});\n", + "}\n", + "\n", + "mpl.figure.prototype.mouse_event = function (event, name) {\n", + " var canvas_pos = mpl.findpos(event);\n", + "\n", + " if (name === 'button_press') {\n", + " this.canvas.focus();\n", + " this.canvas_div.focus();\n", + " }\n", + "\n", + " var x = canvas_pos.x * this.ratio;\n", + " var y = canvas_pos.y * this.ratio;\n", + "\n", + " this.send_message(name, {\n", + " x: x,\n", + " y: y,\n", + " button: event.button,\n", + " step: event.step,\n", + " guiEvent: simpleKeys(event),\n", + " });\n", + "\n", + " /* This prevents the web browser from automatically changing to\n", + " * the text insertion cursor when the button is pressed. We want\n", + " * to control all of the cursor setting manually through the\n", + " * 'cursor' event from matplotlib */\n", + " event.preventDefault();\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", + " // Handle any extra behaviour associated with a key event\n", + "};\n", + "\n", + "mpl.figure.prototype.key_event = function (event, name) {\n", + " // Prevent repeat events\n", + " if (name === 'key_press') {\n", + " if (event.which === this._key) {\n", + " return;\n", + " } else {\n", + " this._key = event.which;\n", + " }\n", + " }\n", + " if (name === 'key_release') {\n", + " this._key = null;\n", + " }\n", + "\n", + " var value = '';\n", + " if (event.ctrlKey && event.which !== 17) {\n", + " value += 'ctrl+';\n", + " }\n", + " if (event.altKey && event.which !== 18) {\n", + " value += 'alt+';\n", + " }\n", + " if (event.shiftKey && event.which !== 16) {\n", + " value += 'shift+';\n", + " }\n", + "\n", + " value += 'k';\n", + " value += event.which.toString();\n", + "\n", + " this._key_event_extra(event, name);\n", + "\n", + " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", + " if (name === 'download') {\n", + " this.handle_save(this, null);\n", + " } else {\n", + " this.send_message('toolbar_button', { name: name });\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", + " this.message.textContent = tooltip;\n", + "};\n", + "\n", + "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", + "// prettier-ignore\n", + "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", + "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", + "\n", + "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", + "\n", + "mpl.default_extension = \"png\";/* global mpl */\n", + "\n", + "var comm_websocket_adapter = function (comm) {\n", + " // Create a \"websocket\"-like object which calls the given IPython comm\n", + " // object with the appropriate methods. Currently this is a non binary\n", + " // socket, so there is still some room for performance tuning.\n", + " var ws = {};\n", + "\n", + " ws.close = function () {\n", + " comm.close();\n", + " };\n", + " ws.send = function (m) {\n", + " //console.log('sending', m);\n", + " comm.send(m);\n", + " };\n", + " // Register the callback with on_msg.\n", + " comm.on_msg(function (msg) {\n", + " //console.log('receiving', msg['content']['data'], msg);\n", + " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", + " ws.onmessage(msg['content']['data']);\n", + " });\n", + " return ws;\n", + "};\n", + "\n", + "mpl.mpl_figure_comm = function (comm, msg) {\n", + " // This is the function which gets called when the mpl process\n", + " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", + "\n", + " var id = msg.content.data.id;\n", + " // Get hold of the div created by the display call when the Comm\n", + " // socket was opened in Python.\n", + " var element = document.getElementById(id);\n", + " var ws_proxy = comm_websocket_adapter(comm);\n", + "\n", + " function ondownload(figure, _format) {\n", + " window.open(figure.canvas.toDataURL());\n", + " }\n", + "\n", + " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", + "\n", + " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", + " // web socket which is closed, not our websocket->open comm proxy.\n", + " ws_proxy.onopen();\n", + "\n", + " fig.parent_element = element;\n", + " fig.cell_info = mpl.find_output_cell(\"
\");\n", + " if (!fig.cell_info) {\n", + " console.error('Failed to find cell for figure', id, fig);\n", + " return;\n", + " }\n", + " fig.cell_info[0].output_area.element.on(\n", + " 'cleared',\n", + " { fig: fig },\n", + " fig._remove_fig_handler\n", + " );\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_close = function (fig, msg) {\n", + " var width = fig.canvas.width / fig.ratio;\n", + " fig.cell_info[0].output_area.element.off(\n", + " 'cleared',\n", + " fig._remove_fig_handler\n", + " );\n", + " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", + "\n", + " // Update the output cell to use the data from the current canvas.\n", + " fig.push_to_output();\n", + " var dataURL = fig.canvas.toDataURL();\n", + " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", + " // the notebook keyboard shortcuts fail.\n", + " IPython.keyboard_manager.enable();\n", + " fig.parent_element.innerHTML =\n", + " '';\n", + " fig.close_ws(fig, msg);\n", + "};\n", + "\n", + "mpl.figure.prototype.close_ws = function (fig, msg) {\n", + " fig.send_message('closing', msg);\n", + " // fig.ws.close()\n", + "};\n", + "\n", + "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", + " // Turn the data on the canvas into data in the output cell.\n", + " var width = this.canvas.width / this.ratio;\n", + " var dataURL = this.canvas.toDataURL();\n", + " this.cell_info[1]['text/html'] =\n", + " '';\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Tell IPython that the notebook contents must change.\n", + " IPython.notebook.set_dirty(true);\n", + " this.send_message('ack', {});\n", + " var fig = this;\n", + " // Wait a second, then push the new image to the DOM so\n", + " // that it is saved nicely (might be nice to debounce this).\n", + " setTimeout(function () {\n", + " fig.push_to_output();\n", + " }, 1000);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'btn-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " var button;\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " continue;\n", + " }\n", + "\n", + " button = fig.buttons[name] = document.createElement('button');\n", + " button.classList = 'btn btn-default';\n", + " button.href = '#';\n", + " button.title = name;\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message pull-right';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = document.createElement('div');\n", + " buttongrp.classList = 'btn-group inline pull-right';\n", + " button = document.createElement('button');\n", + " button.classList = 'btn btn-mini btn-primary';\n", + " button.href = '#';\n", + " button.title = 'Stop Interaction';\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', function (_evt) {\n", + " fig.handle_close(fig, {});\n", + " });\n", + " button.addEventListener(\n", + " 'mouseover',\n", + " on_mouseover_closure('Stop Interaction')\n", + " );\n", + " buttongrp.appendChild(button);\n", + " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", + " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", + "};\n", + "\n", + "mpl.figure.prototype._remove_fig_handler = function (event) {\n", + " var fig = event.data.fig;\n", + " if (event.target !== this) {\n", + " // Ignore bubbled events from children.\n", + " return;\n", + " }\n", + " fig.close_ws(fig, {});\n", + "};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (el) {\n", + " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (el) {\n", + " // this is important to make the div 'focusable\n", + " el.setAttribute('tabindex', 0);\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " } else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager) {\n", + " manager = IPython.keyboard_manager;\n", + " }\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which === 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " fig.ondownload(fig, null);\n", + "};\n", + "\n", + "mpl.find_output_cell = function (html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i = 0; i < ncells; i++) {\n", + " var cell = cells[i];\n", + " if (cell.cell_type === 'code') {\n", + " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", + " var data = cell.output_area.outputs[j];\n", + " if (data.data) {\n", + " // IPython >= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] === html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "};\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel !== null) {\n", + " IPython.notebook.kernel.comm_manager.register_target(\n", + " 'matplotlib',\n", + " mpl.mpl_figure_comm\n", + " );\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[1;31mLoading data from a sequential run/already combined runs of experiment configurations.\u001b[0;0m\n", + "../mdpp_to_cave/a3c_lstm_del\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + "\n", + "
\n", + "
\n", + "
\n", + " \n", + "
\n", + "
\n", + "
\n", + "
\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
DefaultIncumbent
Quality-36.974-40.209
\n", + "
\n", + "
\n", + "
\n", + " \n", + "
" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/pimp/evaluator/local_parameter_importance.py:268: RuntimeWarning: invalid value encountered in double_scalars\n", + " overall_var_per_tree = {p : [t / sum_var_per_tree[idx] for idx, t in enumerate(trees)] for p, trees in\n", + "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/pimp/evaluator/local_parameter_importance.py:402: UserWarning: Attempted to set non-positive top ylim on a log-scaled axis.\n", + "Invalid limit will be ignored.\n", + " ax1.set_ylim([min_y * 0.95, max_y])\n" + ] + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "/* global mpl */\n", + "window.mpl = {};\n", + "\n", + "mpl.get_websocket_type = function () {\n", + " if (typeof WebSocket !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof MozWebSocket !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert(\n", + " 'Your browser does not have WebSocket support. ' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.'\n", + " );\n", + " }\n", + "};\n", + "\n", + "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = this.ws.binaryType !== undefined;\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById('mpl-warnings');\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent =\n", + " 'This browser does not support binary websocket messages. ' +\n", + " 'Performance may be slow.';\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = document.createElement('div');\n", + " this.root.setAttribute('style', 'display: inline-block');\n", + " this._root_extra_style(this.root);\n", + "\n", + " parent_element.appendChild(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message('supports_binary', { value: fig.supports_binary });\n", + " fig.send_message('send_image_mode', {});\n", + " if (fig.ratio !== 1) {\n", + " fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n", + " }\n", + " fig.send_message('refresh', {});\n", + " };\n", + "\n", + " this.imageObj.onload = function () {\n", + " if (fig.image_mode === 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function () {\n", + " fig.ws.close();\n", + " };\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "};\n", + "\n", + "mpl.figure.prototype._init_header = function () {\n", + " var titlebar = document.createElement('div');\n", + " titlebar.classList =\n", + " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", + " var titletext = document.createElement('div');\n", + " titletext.classList = 'ui-dialog-title';\n", + " titletext.setAttribute(\n", + " 'style',\n", + " 'width: 100%; text-align: center; padding: 3px;'\n", + " );\n", + " titlebar.appendChild(titletext);\n", + " this.root.appendChild(titlebar);\n", + " this.header = titletext;\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", + "\n", + "mpl.figure.prototype._init_canvas = function () {\n", + " var fig = this;\n", + "\n", + " var canvas_div = (this.canvas_div = document.createElement('div'));\n", + " canvas_div.setAttribute(\n", + " 'style',\n", + " 'border: 1px solid #ddd;' +\n", + " 'box-sizing: content-box;' +\n", + " 'clear: both;' +\n", + " 'min-height: 1px;' +\n", + " 'min-width: 1px;' +\n", + " 'outline: 0;' +\n", + " 'overflow: hidden;' +\n", + " 'position: relative;' +\n", + " 'resize: both;'\n", + " );\n", + "\n", + " function on_keyboard_event_closure(name) {\n", + " return function (event) {\n", + " return fig.key_event(event, name);\n", + " };\n", + " }\n", + "\n", + " canvas_div.addEventListener(\n", + " 'keydown',\n", + " on_keyboard_event_closure('key_press')\n", + " );\n", + " canvas_div.addEventListener(\n", + " 'keyup',\n", + " on_keyboard_event_closure('key_release')\n", + " );\n", + "\n", + " this._canvas_extra_style(canvas_div);\n", + " this.root.appendChild(canvas_div);\n", + "\n", + " var canvas = (this.canvas = document.createElement('canvas'));\n", + " canvas.classList.add('mpl-canvas');\n", + " canvas.setAttribute('style', 'box-sizing: content-box;');\n", + "\n", + " this.context = canvas.getContext('2d');\n", + "\n", + " var backingStore =\n", + " this.context.backingStorePixelRatio ||\n", + " this.context.webkitBackingStorePixelRatio ||\n", + " this.context.mozBackingStorePixelRatio ||\n", + " this.context.msBackingStorePixelRatio ||\n", + " this.context.oBackingStorePixelRatio ||\n", + " this.context.backingStorePixelRatio ||\n", + " 1;\n", + "\n", + " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", + " 'canvas'\n", + " ));\n", + " rubberband_canvas.setAttribute(\n", + " 'style',\n", + " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n", + " );\n", + "\n", + " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", + " if (this.ResizeObserver === undefined) {\n", + " if (window.ResizeObserver !== undefined) {\n", + " this.ResizeObserver = window.ResizeObserver;\n", + " } else {\n", + " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", + " this.ResizeObserver = obs.ResizeObserver;\n", + " }\n", + " }\n", + "\n", + " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", + " var nentries = entries.length;\n", + " for (var i = 0; i < nentries; i++) {\n", + " var entry = entries[i];\n", + " var width, height;\n", + " if (entry.contentBoxSize) {\n", + " if (entry.contentBoxSize instanceof Array) {\n", + " // Chrome 84 implements new version of spec.\n", + " width = entry.contentBoxSize[0].inlineSize;\n", + " height = entry.contentBoxSize[0].blockSize;\n", + " } else {\n", + " // Firefox implements old version of spec.\n", + " width = entry.contentBoxSize.inlineSize;\n", + " height = entry.contentBoxSize.blockSize;\n", + " }\n", + " } else {\n", + " // Chrome <84 implements even older version of spec.\n", + " width = entry.contentRect.width;\n", + " height = entry.contentRect.height;\n", + " }\n", + "\n", + " // Keep the size of the canvas and rubber band canvas in sync with\n", + " // the canvas container.\n", + " if (entry.devicePixelContentBoxSize) {\n", + " // Chrome 84 implements new version of spec.\n", + " canvas.setAttribute(\n", + " 'width',\n", + " entry.devicePixelContentBoxSize[0].inlineSize\n", + " );\n", + " canvas.setAttribute(\n", + " 'height',\n", + " entry.devicePixelContentBoxSize[0].blockSize\n", + " );\n", + " } else {\n", + " canvas.setAttribute('width', width * fig.ratio);\n", + " canvas.setAttribute('height', height * fig.ratio);\n", + " }\n", + " canvas.setAttribute(\n", + " 'style',\n", + " 'width: ' + width + 'px; height: ' + height + 'px;'\n", + " );\n", + "\n", + " rubberband_canvas.setAttribute('width', width);\n", + " rubberband_canvas.setAttribute('height', height);\n", + "\n", + " // And update the size in Python. We ignore the initial 0/0 size\n", + " // that occurs as the element is placed into the DOM, which should\n", + " // otherwise not happen due to the minimum size styling.\n", + " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", + " fig.request_resize(width, height);\n", + " }\n", + " }\n", + " });\n", + " this.resizeObserverInstance.observe(canvas_div);\n", + "\n", + " function on_mouse_event_closure(name) {\n", + " return function (event) {\n", + " return fig.mouse_event(event, name);\n", + " };\n", + " }\n", + "\n", + " rubberband_canvas.addEventListener(\n", + " 'mousedown',\n", + " on_mouse_event_closure('button_press')\n", + " );\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseup',\n", + " on_mouse_event_closure('button_release')\n", + " );\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband_canvas.addEventListener(\n", + " 'mousemove',\n", + " on_mouse_event_closure('motion_notify')\n", + " );\n", + "\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseenter',\n", + " on_mouse_event_closure('figure_enter')\n", + " );\n", + " rubberband_canvas.addEventListener(\n", + " 'mouseleave',\n", + " on_mouse_event_closure('figure_leave')\n", + " );\n", + "\n", + " canvas_div.addEventListener('wheel', function (event) {\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " on_mouse_event_closure('scroll')(event);\n", + " });\n", + "\n", + " canvas_div.appendChild(canvas);\n", + " canvas_div.appendChild(rubberband_canvas);\n", + "\n", + " this.rubberband_context = rubberband_canvas.getContext('2d');\n", + " this.rubberband_context.strokeStyle = '#000000';\n", + "\n", + " this._resize_canvas = function (width, height, forward) {\n", + " if (forward) {\n", + " canvas_div.style.width = width + 'px';\n", + " canvas_div.style.height = height + 'px';\n", + " }\n", + " };\n", + "\n", + " // Disable right mouse context menu.\n", + " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n", + " event.preventDefault();\n", + " return false;\n", + " });\n", + "\n", + " function set_focus() {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'mpl-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'mpl-button-group';\n", + " continue;\n", + " }\n", + "\n", + " var button = (fig.buttons[name] = document.createElement('button'));\n", + " button.classList = 'mpl-widget';\n", + " button.setAttribute('role', 'button');\n", + " button.setAttribute('aria-disabled', 'false');\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + "\n", + " var icon_img = document.createElement('img');\n", + " icon_img.src = '_images/' + image + '.png';\n", + " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", + " icon_img.alt = tooltip;\n", + " button.appendChild(icon_img);\n", + "\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " var fmt_picker = document.createElement('select');\n", + " fmt_picker.classList = 'mpl-widget';\n", + " toolbar.appendChild(fmt_picker);\n", + " this.format_dropdown = fmt_picker;\n", + "\n", + " for (var ind in mpl.extensions) {\n", + " var fmt = mpl.extensions[ind];\n", + " var option = document.createElement('option');\n", + " option.selected = fmt === mpl.default_extension;\n", + " option.innerHTML = fmt;\n", + " fmt_picker.appendChild(option);\n", + " }\n", + "\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "};\n", + "\n", + "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", + " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", + " // which will in turn request a refresh of the image.\n", + " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", + "};\n", + "\n", + "mpl.figure.prototype.send_message = function (type, properties) {\n", + " properties['type'] = type;\n", + " properties['figure_id'] = this.id;\n", + " this.ws.send(JSON.stringify(properties));\n", + "};\n", + "\n", + "mpl.figure.prototype.send_draw_message = function () {\n", + " if (!this.waiting) {\n", + " this.waiting = true;\n", + " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " var format_dropdown = fig.format_dropdown;\n", + " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", + " fig.ondownload(fig, format);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", + " var size = msg['size'];\n", + " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", + " fig._resize_canvas(size[0], size[1], msg['forward']);\n", + " fig.send_message('refresh', {});\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", + " var x0 = msg['x0'] / fig.ratio;\n", + " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", + " var x1 = msg['x1'] / fig.ratio;\n", + " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", + " x0 = Math.floor(x0) + 0.5;\n", + " y0 = Math.floor(y0) + 0.5;\n", + " x1 = Math.floor(x1) + 0.5;\n", + " y1 = Math.floor(y1) + 0.5;\n", + " var min_x = Math.min(x0, x1);\n", + " var min_y = Math.min(y0, y1);\n", + " var width = Math.abs(x1 - x0);\n", + " var height = Math.abs(y1 - y0);\n", + "\n", + " fig.rubberband_context.clearRect(\n", + " 0,\n", + " 0,\n", + " fig.canvas.width / fig.ratio,\n", + " fig.canvas.height / fig.ratio\n", + " );\n", + "\n", + " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", + " // Updates the figure title.\n", + " fig.header.textContent = msg['label'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", + " var cursor = msg['cursor'];\n", + " switch (cursor) {\n", + " case 0:\n", + " cursor = 'pointer';\n", + " break;\n", + " case 1:\n", + " cursor = 'default';\n", + " break;\n", + " case 2:\n", + " cursor = 'crosshair';\n", + " break;\n", + " case 3:\n", + " cursor = 'move';\n", + " break;\n", + " }\n", + " fig.rubberband_canvas.style.cursor = cursor;\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_message = function (fig, msg) {\n", + " fig.message.textContent = msg['message'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", + " // Request the server to send over a new figure.\n", + " fig.send_draw_message();\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", + " fig.image_mode = msg['mode'];\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", + " for (var key in msg) {\n", + " if (!(key in fig.buttons)) {\n", + " continue;\n", + " }\n", + " fig.buttons[key].disabled = !msg[key];\n", + " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", + " if (msg['mode'] === 'PAN') {\n", + " fig.buttons['Pan'].classList.add('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " } else if (msg['mode'] === 'ZOOM') {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.add('active');\n", + " } else {\n", + " fig.buttons['Pan'].classList.remove('active');\n", + " fig.buttons['Zoom'].classList.remove('active');\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Called whenever the canvas gets updated.\n", + " this.send_message('ack', {});\n", + "};\n", + "\n", + "// A function to construct a web socket function for onmessage handling.\n", + "// Called in the figure constructor.\n", + "mpl.figure.prototype._make_on_message_function = function (fig) {\n", + " return function socket_on_message(evt) {\n", + " if (evt.data instanceof Blob) {\n", + " /* FIXME: We get \"Resource interpreted as Image but\n", + " * transferred with MIME type text/plain:\" errors on\n", + " * Chrome. But how to set the MIME type? It doesn't seem\n", + " * to be part of the websocket stream */\n", + " evt.data.type = 'image/png';\n", + "\n", + " /* Free the memory for the previous frames */\n", + " if (fig.imageObj.src) {\n", + " (window.URL || window.webkitURL).revokeObjectURL(\n", + " fig.imageObj.src\n", + " );\n", + " }\n", + "\n", + " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", + " evt.data\n", + " );\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " } else if (\n", + " typeof evt.data === 'string' &&\n", + " evt.data.slice(0, 21) === 'data:image/png;base64'\n", + " ) {\n", + " fig.imageObj.src = evt.data;\n", + " fig.updated_canvas_event();\n", + " fig.waiting = false;\n", + " return;\n", + " }\n", + "\n", + " var msg = JSON.parse(evt.data);\n", + " var msg_type = msg['type'];\n", + "\n", + " // Call the \"handle_{type}\" callback, which takes\n", + " // the figure and JSON message as its only arguments.\n", + " try {\n", + " var callback = fig['handle_' + msg_type];\n", + " } catch (e) {\n", + " console.log(\n", + " \"No handler for the '\" + msg_type + \"' message type: \",\n", + " msg\n", + " );\n", + " return;\n", + " }\n", + "\n", + " if (callback) {\n", + " try {\n", + " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", + " callback(fig, msg);\n", + " } catch (e) {\n", + " console.log(\n", + " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", + " e,\n", + " e.stack,\n", + " msg\n", + " );\n", + " }\n", + " }\n", + " };\n", + "};\n", + "\n", + "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", + "mpl.findpos = function (e) {\n", + " //this section is from http://www.quirksmode.org/js/events_properties.html\n", + " var targ;\n", + " if (!e) {\n", + " e = window.event;\n", + " }\n", + " if (e.target) {\n", + " targ = e.target;\n", + " } else if (e.srcElement) {\n", + " targ = e.srcElement;\n", + " }\n", + " if (targ.nodeType === 3) {\n", + " // defeat Safari bug\n", + " targ = targ.parentNode;\n", + " }\n", + "\n", + " // pageX,Y are the mouse positions relative to the document\n", + " var boundingRect = targ.getBoundingClientRect();\n", + " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n", + " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n", + "\n", + " return { x: x, y: y };\n", + "};\n", + "\n", + "/*\n", + " * return a copy of an object with only non-object keys\n", + " * we need this to avoid circular references\n", + " * http://stackoverflow.com/a/24161582/3208463\n", + " */\n", + "function simpleKeys(original) {\n", + " return Object.keys(original).reduce(function (obj, key) {\n", + " if (typeof original[key] !== 'object') {\n", + " obj[key] = original[key];\n", + " }\n", + " return obj;\n", + " }, {});\n", + "}\n", + "\n", + "mpl.figure.prototype.mouse_event = function (event, name) {\n", + " var canvas_pos = mpl.findpos(event);\n", + "\n", + " if (name === 'button_press') {\n", + " this.canvas.focus();\n", + " this.canvas_div.focus();\n", + " }\n", + "\n", + " var x = canvas_pos.x * this.ratio;\n", + " var y = canvas_pos.y * this.ratio;\n", + "\n", + " this.send_message(name, {\n", + " x: x,\n", + " y: y,\n", + " button: event.button,\n", + " step: event.step,\n", + " guiEvent: simpleKeys(event),\n", + " });\n", + "\n", + " /* This prevents the web browser from automatically changing to\n", + " * the text insertion cursor when the button is pressed. We want\n", + " * to control all of the cursor setting manually through the\n", + " * 'cursor' event from matplotlib */\n", + " event.preventDefault();\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", + " // Handle any extra behaviour associated with a key event\n", + "};\n", + "\n", + "mpl.figure.prototype.key_event = function (event, name) {\n", + " // Prevent repeat events\n", + " if (name === 'key_press') {\n", + " if (event.which === this._key) {\n", + " return;\n", + " } else {\n", + " this._key = event.which;\n", + " }\n", + " }\n", + " if (name === 'key_release') {\n", + " this._key = null;\n", + " }\n", + "\n", + " var value = '';\n", + " if (event.ctrlKey && event.which !== 17) {\n", + " value += 'ctrl+';\n", + " }\n", + " if (event.altKey && event.which !== 18) {\n", + " value += 'alt+';\n", + " }\n", + " if (event.shiftKey && event.which !== 16) {\n", + " value += 'shift+';\n", + " }\n", + "\n", + " value += 'k';\n", + " value += event.which.toString();\n", + "\n", + " this._key_event_extra(event, name);\n", + "\n", + " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", + " return false;\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", + " if (name === 'download') {\n", + " this.handle_save(this, null);\n", + " } else {\n", + " this.send_message('toolbar_button', { name: name });\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", + " this.message.textContent = tooltip;\n", + "};\n", + "\n", + "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", + "// prettier-ignore\n", + "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", + "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", + "\n", + "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", + "\n", + "mpl.default_extension = \"png\";/* global mpl */\n", + "\n", + "var comm_websocket_adapter = function (comm) {\n", + " // Create a \"websocket\"-like object which calls the given IPython comm\n", + " // object with the appropriate methods. Currently this is a non binary\n", + " // socket, so there is still some room for performance tuning.\n", + " var ws = {};\n", + "\n", + " ws.close = function () {\n", + " comm.close();\n", + " };\n", + " ws.send = function (m) {\n", + " //console.log('sending', m);\n", + " comm.send(m);\n", + " };\n", + " // Register the callback with on_msg.\n", + " comm.on_msg(function (msg) {\n", + " //console.log('receiving', msg['content']['data'], msg);\n", + " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", + " ws.onmessage(msg['content']['data']);\n", + " });\n", + " return ws;\n", + "};\n", + "\n", + "mpl.mpl_figure_comm = function (comm, msg) {\n", + " // This is the function which gets called when the mpl process\n", + " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", + "\n", + " var id = msg.content.data.id;\n", + " // Get hold of the div created by the display call when the Comm\n", + " // socket was opened in Python.\n", + " var element = document.getElementById(id);\n", + " var ws_proxy = comm_websocket_adapter(comm);\n", + "\n", + " function ondownload(figure, _format) {\n", + " window.open(figure.canvas.toDataURL());\n", + " }\n", + "\n", + " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", + "\n", + " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", + " // web socket which is closed, not our websocket->open comm proxy.\n", + " ws_proxy.onopen();\n", + "\n", + " fig.parent_element = element;\n", + " fig.cell_info = mpl.find_output_cell(\"
\");\n", + " if (!fig.cell_info) {\n", + " console.error('Failed to find cell for figure', id, fig);\n", + " return;\n", + " }\n", + " fig.cell_info[0].output_area.element.on(\n", + " 'cleared',\n", + " { fig: fig },\n", + " fig._remove_fig_handler\n", + " );\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_close = function (fig, msg) {\n", + " var width = fig.canvas.width / fig.ratio;\n", + " fig.cell_info[0].output_area.element.off(\n", + " 'cleared',\n", + " fig._remove_fig_handler\n", + " );\n", + " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", + "\n", + " // Update the output cell to use the data from the current canvas.\n", + " fig.push_to_output();\n", + " var dataURL = fig.canvas.toDataURL();\n", + " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", + " // the notebook keyboard shortcuts fail.\n", + " IPython.keyboard_manager.enable();\n", + " fig.parent_element.innerHTML =\n", + " '';\n", + " fig.close_ws(fig, msg);\n", + "};\n", + "\n", + "mpl.figure.prototype.close_ws = function (fig, msg) {\n", + " fig.send_message('closing', msg);\n", + " // fig.ws.close()\n", + "};\n", + "\n", + "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", + " // Turn the data on the canvas into data in the output cell.\n", + " var width = this.canvas.width / this.ratio;\n", + " var dataURL = this.canvas.toDataURL();\n", + " this.cell_info[1]['text/html'] =\n", + " '';\n", + "};\n", + "\n", + "mpl.figure.prototype.updated_canvas_event = function () {\n", + " // Tell IPython that the notebook contents must change.\n", + " IPython.notebook.set_dirty(true);\n", + " this.send_message('ack', {});\n", + " var fig = this;\n", + " // Wait a second, then push the new image to the DOM so\n", + " // that it is saved nicely (might be nice to debounce this).\n", + " setTimeout(function () {\n", + " fig.push_to_output();\n", + " }, 1000);\n", + "};\n", + "\n", + "mpl.figure.prototype._init_toolbar = function () {\n", + " var fig = this;\n", + "\n", + " var toolbar = document.createElement('div');\n", + " toolbar.classList = 'btn-toolbar';\n", + " this.root.appendChild(toolbar);\n", + "\n", + " function on_click_closure(name) {\n", + " return function (_event) {\n", + " return fig.toolbar_button_onclick(name);\n", + " };\n", + " }\n", + "\n", + " function on_mouseover_closure(tooltip) {\n", + " return function (event) {\n", + " if (!event.currentTarget.disabled) {\n", + " return fig.toolbar_button_onmouseover(tooltip);\n", + " }\n", + " };\n", + " }\n", + "\n", + " fig.buttons = {};\n", + " var buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " var button;\n", + " for (var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " /* Instead of a spacer, we start a new button group. */\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + " buttonGroup = document.createElement('div');\n", + " buttonGroup.classList = 'btn-group';\n", + " continue;\n", + " }\n", + "\n", + " button = fig.buttons[name] = document.createElement('button');\n", + " button.classList = 'btn btn-default';\n", + " button.href = '#';\n", + " button.title = name;\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', on_click_closure(method_name));\n", + " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", + " buttonGroup.appendChild(button);\n", + " }\n", + "\n", + " if (buttonGroup.hasChildNodes()) {\n", + " toolbar.appendChild(buttonGroup);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = document.createElement('span');\n", + " status_bar.classList = 'mpl-message pull-right';\n", + " toolbar.appendChild(status_bar);\n", + " this.message = status_bar;\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = document.createElement('div');\n", + " buttongrp.classList = 'btn-group inline pull-right';\n", + " button = document.createElement('button');\n", + " button.classList = 'btn btn-mini btn-primary';\n", + " button.href = '#';\n", + " button.title = 'Stop Interaction';\n", + " button.innerHTML = '';\n", + " button.addEventListener('click', function (_evt) {\n", + " fig.handle_close(fig, {});\n", + " });\n", + " button.addEventListener(\n", + " 'mouseover',\n", + " on_mouseover_closure('Stop Interaction')\n", + " );\n", + " buttongrp.appendChild(button);\n", + " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", + " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", + "};\n", + "\n", + "mpl.figure.prototype._remove_fig_handler = function (event) {\n", + " var fig = event.data.fig;\n", + " if (event.target !== this) {\n", + " // Ignore bubbled events from children.\n", + " return;\n", + " }\n", + " fig.close_ws(fig, {});\n", + "};\n", + "\n", + "mpl.figure.prototype._root_extra_style = function (el) {\n", + " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", + "};\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function (el) {\n", + " // this is important to make the div 'focusable\n", + " el.setAttribute('tabindex', 0);\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " } else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager) {\n", + " manager = IPython.keyboard_manager;\n", + " }\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which === 13) {\n", + " this.canvas_div.blur();\n", + " // select the cell after this one\n", + " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", + " IPython.notebook.select(index + 1);\n", + " }\n", + "};\n", + "\n", + "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", + " fig.ondownload(fig, null);\n", + "};\n", + "\n", + "mpl.find_output_cell = function (html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i = 0; i < ncells; i++) {\n", + " var cell = cells[i];\n", + " if (cell.cell_type === 'code') {\n", + " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", + " var data = cell.output_area.outputs[j];\n", + " if (data.data) {\n", + " // IPython >= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] === html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "};\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel !== null) {\n", + " IPython.notebook.kernel.comm_manager.register_target(\n", + " 'matplotlib',\n", + " mpl.mpl_figure_comm\n", + " );\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "# Setup to analyse an MDP Playground experiment\n", "from mdp_playground.analysis import MDPP_Analysis\n", @@ -422,10 +4578,10 @@ "\n", "#The converted mdpp csvs will be stored in output_dir\n", "output_dir = \"../mdpp_to_cave\"\n", - "mdpp_cave = MDPPToCave(output_dir)\n", + "mdpp_cave = MDPPToCave()\n", "for exp_name, v in experiments.items():\n", " dir_name, _ = os.path.split(v)\n", - " cave_input_file = mdpp_cave.to_bohb_results(dir_name, exp_name)\n", + " cave_input_file = mdpp_cave.to_bohb_results(dir_name, exp_name, output_dir)\n", " print(cave_input_file)\n", " # Similarly, as an example, cave will ouput it's results \n", " # to the same directory as cave's input files\n", @@ -439,7 +4595,22 @@ " )\n", " cave.performance_table()\n", " cave.local_parameter_importance()\n", - " cave.cave_fanova()" + " # cave.cave_fanova() # Only for experiments varying more than 1 meta-feature\n", + "\n", + "# Other analysis\n", + "# cave.parallel_coordinates()\n", + "# cave.cost_over_time()\n", + "# cave.algorithm_footprints()\n", + "# cave.pimp_comparison_table()\n", + "# cave.cave_ablation()\n", + "# cave.pimp_forward_selection()\n", + "# cave.feature_importance()\n", + "# cave.configurator_footprint()\n", + "# cave.algorithm_footprints()\n", + "# cave.plot_ecdf()\n", + "# cave.plot_scatter()\n", + "# cave.compare_default_incumbent()\n", + "# cave.overview_table()" ] }, { diff --git a/rudder_analysis.ipynb b/rudder_analysis.ipynb deleted file mode 100644 index 3ab934a..0000000 --- a/rudder_analysis.ipynb +++ /dev/null @@ -1,715 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "

A step-by-step guide to applying RUDDER

\n", - "\n", - "--- by Michael Widrich (widi) ---\n", - "\n", - "In this tutorial I will show you how RUDDER can be applied step by step and how a reward redistribution model can be implemented using PyTorch.\n", - "You may use it as a quick-guide to apply RUDDER in your RL setting and to pre-assess if RUDDER might lead to improvements for your task beforehand.\n", - "This code should be runnable on common CPUs in reasonable time.\n", - "\n", - "Links to further RUDDER code, our [blog](https://www.jku.at/index.php?id=16426), and [paper](https://arxiv.org/abs/1806.07857) can be found at our [RUDDER repo](https://github.com/ml-jku/rudder)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "

Overview: How to apply RUDDER:

\n", - "I suggest the following procedure to check if RUDDER can help with your RL problem and to apply RUDDER:\n", - "\n", - "1. Draw a set of samples from your environment.\n", - " - A sample is a sequence of observations, actions, and rewards.\n", - " - There should be variance in the returns (sum of rewards) of your samples.\n", - " - Samples do not need to be from the same policy, you may also include human demonstrations and such.\n", - "1. Train an LSTM on your samples (or whatever model-class you want to use for reward redistribution).\n", - " - This part is a supervised ML task.\n", - " - The main task to train on is to predict the return of each sample at the end of the sequence.\n", - " - As auxiliary task, we will train the model to predict the final return at every sequence position. This will allow us to use differences of predictions for contribution analysis and in some cases it also helps to push the reward further back in time. Down-weight the contribution of this task in comparison to the main task\n", - " - If your environment also includes intermediate rewards that are not at the sequence end, you can use auxiliary tasks as described in our paper to introduce gradients via these intermediate rewards to simplify learning.\n", - " - I suggest to try to keep the model as simple as possible, as this made reward redistribution and contribution analysis clearer in my experiments.\n", - " 1. Start with an LSTM without forget gate and without output gate, \n", - " where the cell input only receives forward connections and the gates only receive recurrent connections.\n", - " 1. Increase the model complexity until the model is able to predict the main task (return at the end of the sequence) good enough.\n", - " You can do this by including output gate, forget gate, and fully connected gates, in this order.\n", - "1. Check if the reward redistribution makes sense.\n", - " - Look at the output of the contribution analysis, e.g. the differences of predictions of the LSTM at each sequence position, and check if the reward is redistributed to earlier positions in the sequence.\n", - " - Check if the model is over-fitting. If it is, increase the number of samples or reduce the model complexity.\n", - " - At this point you can get a feeling for if RUDDER might help in your task or not.\n", - "1. Set up a lessons buffer to train the reward redistribution model during training of the agent.\n", - " - From the previous points you should get a feeling for how large the dataset has to be for the LSTM to learn properly.\n", - " - I suggest a lessons buffer that prioritizes samples with higher reward redistribution model loss and that increases the variance of sample returns in the buffer.\n", - "1. Use the reward redistribution to train an agent, e.g. via with PPO.\n", - " - For actor-critic based methods, you can replace the reward signal that the critic would be trained on by the redistributed reward.\n", - " - If your environment has intermediate rewards, you might want to mix the original reward signal with the redistributed reward.\n", - " \n", - "The following sections will show an example for points 1-3, which can serve as pre-assessment if RUDDER might help in your task." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "

Importing packages

\n", - "We'll start by importing the required packages for this guide. I will use my repository widis-lstm-tools v0.4 for the simplified LSTM. You can install it via\n", - "\n", - "```bash\n", - "pip install git+https://github.com/widmi/widis-lstm-tools\n", - "```" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import torch\n", - "import tqdm\n", - "from torch.utils.data import Dataset\n", - "from matplotlib import pyplot as plt\n", - "from widis_lstm_tools.nn import LSTMLayer\n", - "\n", - "# Prepare some random generators for later\n", - "rnd_gen = np.random.RandomState(seed=123)\n", - "_ = torch.manual_seed(123)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "

Creating an example task with delayed reward

\n", - "\n", - "For simplicity, we will create samples for a trivial 1D environment, which we traverse with a random policy. Feel free to replace this environment with samples from your task.\n", - "\n", - "In this environment the agent starts at position 0 and can choose between moving right or left at each timestep, which will increase or decrease the agents position by +1 or -1 respectively.\n", - "Actions that would leave the position range [-6, 6] are ignored, so the number of unique states is restricted to 13. The state only consists of the current position. The agent can take a total of 50 actions per episode, that is each game sequence has a length of 50.\n", - "\n", - "Or visually illustrated:\n", - "\n", - "

\n", - " \n", - "

\n", - "\n", - "If the agent is in state with position 2 it gains +1 reward. \n", - "We turn this task into a delayed reward task where we know what the immediate reward would look like. For this we assume that the reward is not shown to the agent immediately but instead the **accumulated reward is shown at the last timestep**.\n", - "Note that this is not an MDP anymore but for reward redistribution with an LSTM this will not bother us." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "config_file_path: /mnt/484A4CAB4A4C9798/GoogleDrive/Maestria-Drive/HiWi/mdp-playground/experiments\n", - "Number of seeds for environment: 10\n", - "Configuration numbers that will be run: all\n", - "(8, 8, 2, 1, 0.25, False, 0, 0, 0, 0)\n", - "Passed config: {'seed': 0, 'state_space_type': 'discrete', 'action_space_type': 'discrete', 'generate_random_mdp': True, 'repeats_in_sequences': False, 'reward_scale': 1.0, 'completely_connected': True, 'state_space_size': 8, 'action_space_size': 8, 'delay': 2, 'sequence_length': 1, 'reward_density': 0.25, 'make_denser': False, 'terminal_state_density': 0, 'transition_noise': 0, 'reward_noise': . at 0x7f5103786a60>, 'reward_noise_std': 0, 'dummy_seed': 0} \n", - "\n", - "\u001b[32;1m========================================================Initialising Toy MDP========================================================\u001b[0m\n", - "Current working directory: /mnt/484A4CAB4A4C9798/GoogleDrive/Maestria-Drive/HiWi/mdp-playground\n", - "Env SEED set to: 0. Returned seed from Gym: 0\n", - "transition_matrix inited to:\n", - "[[7 6 0 3 4 5 2 1]\n", - " [7 6 4 1 2 0 3 5]\n", - " [5 7 4 6 3 1 0 2]\n", - " [2 4 3 6 5 7 1 0]\n", - " [3 6 4 2 7 1 5 0]\n", - " [4 2 1 5 6 3 0 7]\n", - " [5 7 1 4 6 2 3 0]\n", - " [5 6 1 3 2 0 7 4]]\n", - "Python type of state: \n", - "rewardable_sequences: {(7,): 1.0, (4,): 1.0}\n", - "MDP Playground toy env instantiated with config: {'seed': 0, 'state_space_type': 'discrete', 'action_space_type': 'discrete', 'generate_random_mdp': True, 'repeats_in_sequences': False, 'reward_scale': 1.0, 'completely_connected': True, 'state_space_size': 8, 'action_space_size': 8, 'delay': 2, 'sequence_length': 1, 'reward_density': 0.25, 'make_denser': False, 'terminal_state_density': 0, 'transition_noise': 0, 'reward_noise': . at 0x7f5103786a60>, 'reward_noise_std': 0, 'dummy_seed': 0, 'terminal_states': array([], dtype=float64), 'relevant_init_state_dist': array([0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125]), 'transition_function': . at 0x7f5103786d90>}\n", - "125\n" - ] - } - ], - "source": [ - "import importlib\n", - "import mdp_playground\n", - "from mdp_playground.envs import RLToyEnv\n", - "\n", - "import sys, os\n", - "import argparse\n", - "import importlib\n", - "\n", - "import default_config\n", - "from run_experiments_baselines import *\n", - "\n", - "class Environment(Dataset):\n", - " def __init__(self, n_samples: int, max_timestep: int, rnd_gen: np.random.RandomState):\n", - " \"\"\"Our simple 1D environment as PyTorch Dataset\"\"\"\n", - " super(Environment, self).__init__()\n", - " # arguments\n", - " config_file = './experiments/a3c_del.py'\n", - " config_num = None\n", - "\n", - " # init code\n", - " config_file_path = os.path.abspath('/'.join(config_file.split('/')[:-1]))\n", - " sys.path.insert(1, config_file_path)\n", - " import a3c_del as config\n", - " print(\"config_file_path:\", config_file_path)\n", - "\n", - " #config = importlib.import_module(config_file.split('/')[-1], package=None)\n", - " print(\"Number of seeds for environment:\", config.num_seeds)\n", - " print(\"Configuration numbers that will be run:\", \"all\" if config_num is None else config_num)\n", - "\n", - "\n", - " #------------------------- Variable configurations ----------------------------#\n", - " config, var_agent_configs, var_model_configs = agent_to_baselines(config)\n", - " var_configs_deepcopy = copy.deepcopy(config.var_configs) #hack because this needs to be read in on_train_result and trying to read config there raises an error because it's been imported from a Python module and I think they try to reload it there.\n", - "\n", - " if \"env\" in config.var_configs:\n", - " var_env_configs = config.var_configs[\"env\"] #hack\n", - " else:\n", - " var_env_configs = []\n", - "\n", - " #---------- Compute cartesian product of configs ----------------#\n", - " # cartesian_product_configs = cartesian_prod(args, config)\n", - " if config_num is None:\n", - " cartesian_product_configs = config.cartesian_product_configs\n", - " else:\n", - " cartesian_product_configs = [config.cartesian_product_configs[config_num]]\n", - "\n", - " #------------ Run every configuration ------------------ #\n", - " pp = pprint.PrettyPrinter(indent=4)\n", - " # for i, current_config in enumerate(cartesian_product_configs):\n", - " # print(\"Configuration: %d \\t %d remaining\"%(i, len(cartesian_product_configs) - i ))\n", - "\n", - " current_config = cartesian_product_configs[20]\n", - " print(current_config)\n", - " #------------ Dictionaries setup ------------------ #\n", - " agent_config, model_config, env_config = process_dictionaries(config, current_config, var_env_configs, var_agent_configs, var_model_configs)\n", - "\n", - " #------------ Env init ------------------ #\n", - " # Generate random action sequences\n", - " env = gym.make(env_config['env'],**env_config['env_config'])\n", - " \n", - " # Generate random action sequences\n", - " total_ep = 15\n", - " lessons_buffer = []\n", - " for e in range(n_samples):\n", - " s = env.reset()\n", - " lessons_buffer.append([])\n", - " for ts in range(max_timestep):\n", - " a = env.action_space.sample()\n", - " ns, r, d, _ = env.step(a)\n", - " # print(s, a, r)\n", - " lessons_buffer[e].append([s, a, r, ns])\n", - " s = ns\n", - " # shape = (n_samples, max_timestep, 4)\n", - " lessons_buffer = np.array(lessons_buffer)\n", - " \n", - " a = np.expand_dims(lessons_buffer[:, :, 1], -1).astype(int)\n", - " n_actions = env.action_space.n # For discrete action_spaces\n", - " b = np.zeros((a.size, n_actions + 1))\n", - " # use advanced indexing to get one-hot encoding\n", - " b[np.arange(a.size), a.ravel()] = 1\n", - " # reshape to original form\n", - " actions_onehot = b.reshape(a.shape[:-1] + (n_actions + 1,))\n", - " \n", - " # Generate observations from action sequences\n", - " obs = np.expand_dims(lessons_buffer[:, :, 0], -1).astype(int)\n", - " n_obs = env.observation_space.n # For discrete action_spaces\n", - " b = np.zeros((obs.size, n_obs + 1))\n", - " # use advanced indexing to get one-hot encoding\n", - " b[np.arange(obs.size), obs.ravel()] = 1\n", - " # reshape to original form\n", - " observations_onehot = b.reshape(obs.shape[:-1] + (n_obs + 1,))\n", - " \n", - " # Calculate rewards (sum over coin position for all timesteps)\n", - " rewards = lessons_buffer[:, :, 2]\n", - " \n", - " self.actions = actions_onehot\n", - " self.observations = observations_onehot\n", - " self.rewards = rewards\n", - " \n", - " def __len__(self):\n", - " return self.rewards.shape[0]\n", - " \n", - " def __getitem__(self, idx):\n", - " return self.observations[idx], self.actions[idx], self.rewards[idx]\n", - "\n", - " \n", - "n_positions = 13\n", - "env = Environment(n_samples=1000, max_timestep=100, rnd_gen=rnd_gen)\n", - "env_loader = torch.utils.data.DataLoader(env, batch_size=8, num_workers=4)\n", - "\n", - "print(len(env_loader))\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let's take a look at one of the samples:" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(100, 9)\n", - "[4 5 5 2 6 7 5 6 3 0 7 7 7 6 1 4 7 4 7 4 6 4 0 0 6 6 6 4 3 0 6 0 2 4 2 0 1\n", - " 3 7 0 1 6 7 1 1 0 2 2 6 2 7 5 5 3 4 1 4 1 1 5 3 6 5 3 4 5 1 7 2 2 2 4 4 4\n", - " 1 2 0 3 7 6 0 5 5 7 5 6 1 4 2 5 0 5 1 1 5 2 3 7 5 5]\n" - ] - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "obs0, a0, r0 = env.__getitem__(3)\n", - "obs1, a1, r1 = env.__getitem__(25)\n", - "fig, axes = plt.subplots(3, 2, figsize=(8, 4.5), dpi=100)\n", - "print(obs0.shape)\n", - "mean = np.mean(obs0.argmax(-1))\n", - "print(obs1.argmax(-1))\n", - "axes[0, 0].plot(obs0.argmax(-1))\n", - "axes[0, 1].plot(obs1.argmax(-1))\n", - "axes[0, 0].set_ylim(0, 8)\n", - "axes[0, 1].set_ylim(0, 8)\n", - "axes[0, 0].xaxis.grid(True)\n", - "axes[0, 1].xaxis.grid(True)\n", - "axes[0, 0].set_title('observations (sample 1)')\n", - "axes[0, 1].set_title('observations (sample 2)')\n", - "axes[0, 0].set_xlabel('time (environment steps)')\n", - "axes[0, 1].set_xlabel('time (environment steps)')\n", - "\n", - "axes[1, 0].plot(a0.argmax(-1))\n", - "axes[1, 1].plot(a1.argmax(-1))\n", - "axes[1, 0].xaxis.grid(True)\n", - "axes[1, 1].xaxis.grid(True)\n", - "axes[1, 0].set_title('actions (sample 1)')\n", - "axes[1, 1].set_title('actions (sample 2)')\n", - "axes[1, 0].set_xlabel('time (environment steps)')\n", - "axes[1, 1].set_xlabel('time (environment steps)')\n", - "\n", - "axes[2, 0].plot(r0)\n", - "axes[2, 1].plot(r1)\n", - "axes[2, 0].xaxis.grid(True)\n", - "axes[2, 1].xaxis.grid(True)\n", - "axes[2, 0].set_title('original rewards (sample 1)')\n", - "axes[2, 1].set_title('original rewards (sample 2)')\n", - "axes[2, 0].set_xlabel('time (environment steps)')\n", - "axes[2, 1].set_xlabel('time (environment steps)')\n", - "\n", - "fig.tight_layout()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "... we can see that we created a delayed reward task. Everytime the agent is at position 2 it receives +1 reward at the end of the sequence.\n", - "\n", - "Now let's see what RUDDER can do for us in such a case." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "

Training a reward redistribution model

\n", - "\n", - "We will now train an LSTM model to perform reward redistribution on this task." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "

Defining the model

\n", - "\n", - "Our model will consist of one LSTM layer with 16 cells. We will feed concatenated actions and observations timestep by timestep into the network. We could also use separate networks to preprocess actions and observations. In our experiments it helped to have the number of action- and observation features similar before concatenation. In practice it might not always be necessary to also feed the deltas of the observations, like we did in our paper and for the Atari games. In this example I will omit this.\n", - "\n", - "We will start with a simplified LSTM model without forget gate and without output gate. Additionally, we will only connect the input gate to the recurrent connections and the cell input to the forward connections. The output function of our LSTM will be linear since we are performing regression to predict the return value.\n", - "\n", - "In case our model would not be good enough to predict the return at the end of the sequence, we would have to increase the model complexity until it is good enough. You can do this by including output gate, forget gate, and fully connected gates, in this order." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "class Net(torch.nn.Module):\n", - " def __init__(self, n_positions, n_actions, n_lstm):\n", - " super(Net, self).__init__()\n", - " \n", - " # This will create an LSTM layer where we will feed the concatenate\n", - " self.lstm1 = LSTMLayer(\n", - " in_features=n_positions+n_actions, out_features=n_lstm, inputformat='NLC',\n", - " # cell input: initialize weights to forward inputs with xavier, disable connections to recurrent inputs\n", - " w_ci=(torch.nn.init.xavier_normal_, False),\n", - " # input gate: disable connections to forward inputs, initialize weights to recurrent inputs with xavier\n", - " w_ig=(False, torch.nn.init.xavier_normal_),\n", - " # output gate: disable all connection (=no forget gate) and disable bias\n", - " w_og=False, b_og=False,\n", - " # forget gate: disable all connection (=no forget gate) and disable bias\n", - " w_fg=False, b_fg=False,\n", - " # LSTM output activation is set to identity function\n", - " a_out=lambda x: x\n", - " )\n", - " \n", - " # After the LSTM layer, we add a fully connected output layer\n", - " self.fc_out = torch.nn.Linear(n_lstm, 1)\n", - " \n", - " def forward(self, observations, actions):\n", - " # Process input sequence by LSTM\n", - " lstm_out, *_ = self.lstm1(torch.cat([observations, actions], dim=-1),\n", - " return_all_seq_pos=True # return predictions for all sequence positions\n", - " )\n", - " net_out = self.fc_out(lstm_out)\n", - " return net_out\n", - "\n", - "\n", - "# Create Network\n", - "device = 'cpu'\n", - "net = Net(n_positions=n_positions, n_actions=2, n_lstm=16)\n", - "_ = net.to(device)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "

Defining the loss function

\n", - "\n", - "As mentioned in the overview, we will train on two tasks:\n", - "\n", - "1. The **main task** to train on is to predict the return of each sample at the end of the sequence.\n", - "2. The **auxiliary task** is to train the model to predict the final return at every sequence position. This will allow us to perform contribution analysis via differences of predictions. In some cases this helps to push the reward further back in time. Predicting the final return at every sequence position will typically be a lot more difficult for the LSTM since it needs to predict the unknown future. However, the LSTM does not need to be perfect at this task since having a correct return decomposition depends only on the prediction at the last timestep (main task). \n", - "\n", - "We do not have any intermediate rewards in the sequence, so we will only use these two tasks (main task, auxiliary task). We will downweight the auxiliary task with a factor of 0.5. Given the model output (=predictions) and the sequence of rewards we compute our loss as follows:" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [], - "source": [ - "def lossfunction(predictions, rewards):\n", - " returns = rewards.sum(dim=1)\n", - " # Main task: predicting return at last timestep\n", - " main_loss = torch.mean(predictions[:, -1] - returns) ** 2\n", - " # Auxiliary task: predicting final return at every timestep ([..., None] is for correct broadcasting)\n", - " aux_loss = torch.mean(predictions[:, :] - returns[..., None]) ** 2\n", - " # Combine losses\n", - " loss = main_loss + aux_loss * 0.5\n", - " return loss" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "

Training the model

\n", - "\n", - "Now we train our model:" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\r", - " 0%| | 0/10000 [00:00\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 15\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 16\u001b[0m \u001b[0;31m# Get outputs for network\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 17\u001b[0;31m \u001b[0moutputs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnet\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mobservations\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mobservations\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mactions\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mactions\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 18\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 19\u001b[0m \u001b[0;31m# Calculate loss, do backward pass, and update\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/torch/nn/modules/module.py\u001b[0m in \u001b[0;36m_call_impl\u001b[0;34m(self, *input, **kwargs)\u001b[0m\n\u001b[1;32m 887\u001b[0m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_slow_forward\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0minput\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 888\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 889\u001b[0;31m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mforward\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0minput\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 890\u001b[0m for hook in itertools.chain(\n\u001b[1;32m 891\u001b[0m \u001b[0m_global_forward_hooks\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalues\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m\u001b[0m in \u001b[0;36mforward\u001b[0;34m(self, observations, actions)\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[0;31m# Process input sequence by LSTM\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 25\u001b[0m lstm_out, *_ = self.lstm1(torch.cat([observations, actions], dim=-1),\n\u001b[0;32m---> 26\u001b[0;31m \u001b[0mreturn_all_seq_pos\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m \u001b[0;31m# return predictions for all sequence positions\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 27\u001b[0m )\n\u001b[1;32m 28\u001b[0m \u001b[0mnet_out\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfc_out\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlstm_out\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/torch/nn/modules/module.py\u001b[0m in \u001b[0;36m_call_impl\u001b[0;34m(self, *input, **kwargs)\u001b[0m\n\u001b[1;32m 887\u001b[0m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_slow_forward\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0minput\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 888\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 889\u001b[0;31m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mforward\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0minput\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 890\u001b[0m for hook in itertools.chain(\n\u001b[1;32m 891\u001b[0m \u001b[0m_global_forward_hooks\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mvalues\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/widis_lstm_tools/nn.py\u001b[0m in \u001b[0;36mforward\u001b[0;34m(self, x, return_all_seq_pos, true_seq_lens, reset_state)\u001b[0m\n\u001b[1;32m 985\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 986\u001b[0m \u001b[0;31m# Calculate activations for LSTM inlets and append them to self.lstm_inlets_activations\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 987\u001b[0;31m \u001b[0mcell_rets\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__apply_cell__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mh\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mc\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 988\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mc\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0mcell_rets\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 989\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mh\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0mcell_rets\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/widis_lstm_tools/nn.py\u001b[0m in \u001b[0;36m__apply_cell__\u001b[0;34m(self, fwd_inputs, h_old, c_old)\u001b[0m\n\u001b[1;32m 892\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mfwd_input\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0munbind_inputs\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfwd_inputs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 893\u001b[0m \u001b[0;31m# Calculate activations for LSTM inlets and append them to self.lstm_inlets_activations\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 894\u001b[0;31m \u001b[0mcell_rets\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlstm_cell\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcell\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfwd_input\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mh_old\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mc_old\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 895\u001b[0m \u001b[0mc_old\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcell_rets\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 896\u001b[0m \u001b[0mh_old\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcell_rets\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/widis_lstm_tools/nn.py\u001b[0m in \u001b[0;36mcell\u001b[0;34m(self, fwd_inputs, rec_input, c_old)\u001b[0m\n\u001b[1;32m 235\u001b[0m \u001b[0mContains\u001b[0m \u001b[0mcell\u001b[0m \u001b[0mstate\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcell\u001b[0m \u001b[0moutput\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcell\u001b[0m \u001b[0minput\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0minput\u001b[0m \u001b[0mgate\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0moutput\u001b[0m \u001b[0mgate\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mforget\u001b[0m \u001b[0mgate\u001b[0m \u001b[0mactivations\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 236\u001b[0m \"\"\"\n\u001b[0;32m--> 237\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__traced_cell__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfwd_inputs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrec_input\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mc_old\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mw_fwd_cat\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mw_rec_cat\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mb_cat\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 238\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 239\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mcell_tickersteps\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrec_input\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mc_old\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/widis_lstm_tools/nn.py\u001b[0m in \u001b[0;36m__cell_python__\u001b[0;34m(self, fwd_input, rec_input, c_old, w_fwd_cat, w_rec_cat, b)\u001b[0m\n\u001b[1;32m 276\u001b[0m \u001b[0;31m# Compute activations for concatenated weights and split them to inlets\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 277\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mn_fwd_features\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 278\u001b[0;31m \u001b[0mnet_fwds_cat\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmm\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfwd_input\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mw_fwd_cat\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 279\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 280\u001b[0m \u001b[0mnet_fwds_cat\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mzeros_like\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfwd_input\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mRuntimeError\u001b[0m: mat1 and mat2 shapes cannot be multiplied (8x18 and 15x16)" - ] - } - ], - "source": [ - "optimizer = torch.optim.Adam(net.parameters(), lr=1e-3, weight_decay=1e-5)\n", - "\n", - "update = 0\n", - "n_updates = 10000\n", - "running_loss = 100.\n", - "progressbar = tqdm.tqdm(total=n_updates)\n", - "while update < n_updates:\n", - " for data in env_loader:\n", - " # Get samples\n", - " observations, actions, rewards = data\n", - " observations, actions, rewards = observations.to(device), actions.to(device), rewards.to(device)\n", - " \n", - " # Reset gradients\n", - " optimizer.zero_grad()\n", - " \n", - " # Get outputs for network\n", - " outputs = net(observations=observations, actions=actions)\n", - " \n", - " # Calculate loss, do backward pass, and update\n", - " loss = lossfunction(outputs[..., 0], rewards)\n", - " loss.backward()\n", - " running_loss = running_loss*0.99 + loss*0.01\n", - " optimizer.step()\n", - " update += 1\n", - " progressbar.set_description(f\"Loss: {running_loss:8.4f}\")\n", - " progressbar.update(1)\n", - "\n", - "progressbar.close()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "

Computing the reward redistribution

\n", - "\n", - "We can now compute the reward redistribution as the differences of predictions of our trained model. In the optimal case, the reward would be redistributed to the actions that caused the reward and return. In practice, it will be distributed to what the model uses to predict the return, which might e.g. be prominent states. This is where the auxiliary task will help to move the reward further back.\n", - "Naturally, the better the LSTM predictions are, the better this reward redistribution will be.\n", - "\n", - "Let's compute the reward redistribution using our trained model:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Load 2 samples\n", - "obs0, a0, r0 = env.__getitem__(3)\n", - "obs1, a1, r1 = env.__getitem__(25)\n", - "\n", - "# Apply our reward redistribution model to the samples\n", - "observations = torch.stack([torch.Tensor(obs0).to(device), torch.Tensor(obs1).to(device)], dim=0)\n", - "actions = torch.stack([torch.Tensor(a0).to(device), torch.Tensor(a1).to(device)], dim=0)\n", - "rewards = torch.stack([torch.Tensor(r0).to(device), torch.Tensor(r1).to(device)], dim=0)\n", - "predictions = net(observations=observations.to(device), actions=actions.to(device))[..., 0]\n", - "\n", - "# Use the differences of predictions as redistributed reward\n", - "redistributed_reward = predictions[:, 1:] - predictions[:, :-1]\n", - "\n", - "# For the first timestep we will take (0-predictions[:, :1]) as redistributed reward\n", - "redistributed_reward = torch.cat([predictions[:, :1], redistributed_reward], dim=1)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can also enforce that the new and the original sequence have the same return.\n", - "We will do this by calculating the prediction error and distributing the correction for the error equally over all sequence position:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Calculate prediction error\n", - "returns = rewards.sum(dim=1)\n", - "predicted_returns = redistributed_reward.sum(dim=1)\n", - "prediction_error = returns - predicted_returns\n", - "\n", - "# Distribute correction for prediction error equally over all sequence positions\n", - "redistributed_reward += prediction_error[:, None] / redistributed_reward.shape[1]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "

Inspecting the reward redistribution

\n", - "\n", - "Finally, let's take a look at the reward redistribution for our 2 samples:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Let's plot our samples with the redistributed rewards:\n", - "redistributed_reward = redistributed_reward.cpu().detach().numpy()\n", - "rr0, rr1 = redistributed_reward[0], redistributed_reward[1]\n", - "\n", - "fig, axes = plt.subplots(4, 2, figsize=(8, 6), dpi=100)\n", - "axes[0, 0].plot(obs0.argmax(-1) - 6)\n", - "axes[0, 1].plot(obs1.argmax(-1) - 6)\n", - "axes[0, 0].set_ylim(-6, 6)\n", - "axes[0, 1].set_ylim(-6, 6)\n", - "axes[0, 0].axhline(2, linestyle='--', color='r')\n", - "axes[0, 1].axhline(2, linestyle='--', color='r')\n", - "axes[0, 0].xaxis.grid(True)\n", - "axes[0, 1].xaxis.grid(True)\n", - "axes[0, 0].set_title('observations (sample 1)')\n", - "axes[0, 1].set_title('observations (sample 2)')\n", - "axes[0, 0].set_xlabel('time (environment steps)')\n", - "axes[0, 1].set_xlabel('time (environment steps)')\n", - "\n", - "axes[1, 0].plot(a0.argmax(-1))\n", - "axes[1, 1].plot(a1.argmax(-1))\n", - "axes[1, 0].xaxis.grid(True)\n", - "axes[1, 1].xaxis.grid(True)\n", - "axes[1, 0].set_title('actions (sample 1)')\n", - "axes[1, 1].set_title('actions (sample 2)')\n", - "axes[1, 0].set_xlabel('time (environment steps)')\n", - "axes[1, 1].set_xlabel('time (environment steps)')\n", - "\n", - "axes[2, 0].plot(r0)\n", - "axes[2, 1].plot(r1)\n", - "axes[2, 0].xaxis.grid(True)\n", - "axes[2, 1].xaxis.grid(True)\n", - "axes[2, 0].set_title('original rewards (sample 1)')\n", - "axes[2, 1].set_title('original rewards (sample 2)')\n", - "axes[2, 0].set_xlabel('time (environment steps)')\n", - "axes[2, 1].set_xlabel('time (environment steps)')\n", - "\n", - "axes[3, 0].plot(rr0)\n", - "axes[3, 1].plot(rr1)\n", - "axes[3, 0].xaxis.grid(True)\n", - "axes[3, 1].xaxis.grid(True)\n", - "axes[3, 0].set_title('redistributed rewards (sample 1)')\n", - "axes[3, 1].set_title('redistributed rewards (sample 2)')\n", - "axes[3, 0].set_xlabel('time (environment steps)')\n", - "axes[3, 1].set_xlabel('time (environment steps)')\n", - "\n", - "fig.tight_layout()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We can see that the reward that was originally only given at the end is moved to actions that bring the agent closer to position 2.\n", - "\n", - "That means that **we do not recover the environment** where the agent receives +1 reward for being at position 2 **but instead get an environment with rewards that have even shorter delay**, since the actions towards position 2 are immediately rewarded...\n", - "\n", - "... and we achieved all of this with a **supervised ML approach**!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "

A note on LSTM training

\n", - "\n", - "Take a look at the cell states and activations to check if your LSTM is doing something useful or just overfits to e.g. the sequence length or goes into saturation somewhere.\n", - "\n", - "The LSTM states after training would look something like this for sample 1 in the previous plots:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Plost LSTM states for first sample of last processed minibatch\n", - "net.lstm1.plot_internals(filename=None, show_plot=True, mb_index=0, fdict=dict(figsize=(8, 8), dpi=100))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "

A note on contribution analysis

\n", - "\n", - "We found **differences of predictions** to be a well suited method for contribution analysis in our experiments. Mainly due to three nice properties:\n", - "\n", - "1. The **reward redistribution model already performs some averaging over the future** (since it has to predict the final return early in the sequence). This makes learning for the underlying RL agent/method easier. However, this is also the downside of this approach, since the reward redistribution model now not only has to learn to predict the return at the last sequence position. Other contribution analysis methods, such as integrated gradients or layer-wise relevance propagation, do not require the reward redistribution model to learn this prediction at every sequence position, since they can perform contribution analysis based on the prediction at the last sequence position. However, this also means that the agent might receive reward for events that happen in the future, if the contribution analysis comes from the end of the completed episode sequence.\n", - "2. The reward redistribution model trained on predicting the return at the last sequence position will use information from arbitrary sequence positions to do its prediction. However, we would like to **redistribute the reward as far back to the sequence beginning as possible** to decrease the delay between action and corresponding reward. That means we want the reward redistribution model to **detect information that is useful for the prediction of the return as early in the sequence as possible**. And this is exactly what this auxiliary task does. E.g.: Predicting the outcome of a football game is easy by counting when a team scores a goal. The model is therefore likely to use these prominent events for its prediction. Since we are interested not only in assigning reward to those events but even further back to the actions that caused it (some good play that lead to the goal), we have to push the model to do its prediction as early as possible.\n", - "3. Using the differences of the predictions at each sequence position implies that **we can easily perform contribution analysis on incomplete sequences**. Hence, we do not need to need to wait until the episode sequence is completed to perform contribution analysis and train our RL agent/method with the redistributed reward. In practice, **we can keep training the reward redistribution model on the completed episodes in the lessons buffer** in the background while we use the same reward redistribution model to perform **online reward redistribution on new sequences** that are sampled from the environment. This allows for **training an agent with redistributed reward in an online fashion**." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "

What is left to do?

\n", - "\n", - "At this point you might already be able to assess whether RUDDER helps in your task. You then have to set up a lessons buffer to train your reward redistribution model as the policy changes and feed your RL agent/method with the redistributed reward, as described in points 4 and 5 in the overview.\n", - "\n", - "For more details please see our [blog](https://www.jku.at/index.php?id=16426), [paper](https://arxiv.org/abs/1806.07857), and our [RUDDER repo](https://github.com/ml-jku/rudder).\n", - "\n", - "Many thanks to Johannes Brandstetter for proof-reading and testing!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "I hope this tutorial was able to help you and wish you the best for your RL endeavors!\n", - "\n", - "-- Michael Widrich (widi)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.12" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/run_experiments.py b/run_experiments.py index db51cfc..473888a 100644 --- a/run_experiments.py +++ b/run_experiments.py @@ -37,16 +37,19 @@ def main(): #set default value framework = "ray" - #Run file + # Run file print("Running framework:", framework) if(framework == "stable_baselines"): import run_experiments_baselines run_experiments_baselines.main(args) - elif( framework == "custom"): + elif(framework == "stable_baselines3"): + import run_experiments_baselines3 + run_experiments_baselines3.main(args) + elif(framework == "custom"): import run_experiments_custom run_experiments_custom.main(args) return - else: #ray + else: # ray import run_experiments_ray run_experiments_ray.main(args)#_ray.main(args) diff --git a/run_experiments_baselines3.py b/run_experiments_baselines3.py new file mode 100644 index 0000000..4511d5a --- /dev/null +++ b/run_experiments_baselines3.py @@ -0,0 +1,501 @@ +'''Script to run experiments on MDP Playground. + +Takes a configuration file, experiment name and config number to run as optional arguments. +''' +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import numpy as np +import copy + +import mdp_playground +from mdp_playground.envs import RLToyEnv + +import sys, os +import argparse +import importlib + +import default_config +print("default_config:", default_config) + +import gym +from gym.wrappers.time_limit import TimeLimit + +import torch +import torch.nn as nn +from stable_baselines3.common.vec_env import DummyVecEnv +from stable_baselines3.common.monitor import Monitor +from stable_baselines3 import PPO, DQN, DDPG, SAC, A2C, TD3 +from stable_baselines3.common.callbacks import EveryNTimesteps, BaseCallback +from stable_baselines3.common.torch_layers import BaseFeaturesExtractor +from stable_baselines3.common.evaluation import evaluate_policy +from stable_baselines3.common.vec_env import DummyVecEnv, VecEnv, sync_envs_normalization +from typing import Any, Dict, List, Optional, Union + +from functools import reduce +import time +import itertools +import pprint + +#-------------- Custom Classes ------------# +class VisionNet(BaseFeaturesExtractor): + def __init__(self, observation_space: gym.spaces.Box, features_dim: int = 512, **kwargs): + super(VisionNet, self).__init__(observation_space, features_dim) + # We assume CxHxW images (channels first) + # Re-ordering will be done by pre-preprocessing or wrapper + + n_input_channels = observation_space.shape[0] + + if ("act_fun" in kwargs): + activ_fn = kwargs['activation_fun'] + else: #default + activ_fn = nn.ReLU + + #Create Cnn + modules = [] + for i, layer_def in enumerate(kwargs['cnn_layers']): + n_filters, kernel, padding = layer_def + modules.append(nn.Conv2d(n_input_channels, n_filters, kernel_size = kernel, stride = 1, padding = padding)) + modules.append(activ_fn()) + modules.append(nn.Flatten()) + self.cnn = nn.Sequential(*modules) + + # Compute shape by doing one forward pass + with torch.no_grad(): + n_flatten = self.cnn(torch.as_tensor(observation_space.sample()[None]).permute(0,-1, 1, 2).float()).shape[1] + + self.linear = nn.Sequential(nn.Linear(n_flatten, features_dim), activ_fn) + + def forward(self, observations: torch.Tensor) -> torch.Tensor: + return self.linear(self.cnn(observations.permute(0,-1, 1, 2))) + +class CustomCallback(BaseCallback): + """ + Callback for evaluating an agent. + :param eval_env: (Union[gym.Env, VecEnv]) The environment used for initialization + :param n_eval_episodes: (int) The number of episodes to test the agent + :param eval_freq: (int) Evaluate the agent every eval_freq call of the callback. + :param deterministic: (bool) Whether the evaluation should use a stochastic or deterministic actions. + :param verbose: (int) + """ + + def __init__( + self, + eval_env: Union[gym.Env, VecEnv], + n_eval_episodes: int = 5, + eval_freq: int = 10000, + deterministic: bool = True, + verbose: int = 1, + file_name: str = "./evaluation.csv", + config_algorithm: str ="" + ): + super(CustomCallback, self).__init__(verbose=verbose) + self.n_eval_episodes = n_eval_episodes + self.eval_freq = eval_freq + self.deterministic = deterministic + self.file_name = file_name + self.training_iteration = 0 + self.config_algorithm = config_algorithm + + # Convert to VecEnv for consistency + if not isinstance(eval_env, VecEnv): + eval_env = DummyVecEnv([lambda: eval_env]) + + if isinstance(eval_env, VecEnv): + assert eval_env.num_envs == 1, "You must pass only one environment for evaluation" + + self.eval_env = eval_env + + #evaluate policy when step % eval_freq == 0, return rewards and lengths list of n_eval_episodes elements + def _on_step(self) -> bool: + + if self.eval_freq > 0 and self.n_calls % self.eval_freq == 0: + # Sync training and eval env if there is VecNormalize + sync_envs_normalization(self.training_env, self.eval_env) + + episode_rewards, episode_lengths = evaluate_policy( + self.model, + self.eval_env, + n_eval_episodes=self.n_eval_episodes, + render=False, + deterministic=self.deterministic, + return_episode_rewards=True, + ) + + #Write train stats at the end of every training iteration + #on_train_result(self.training_env, self.training_iteration, self.file_name, self.config_algorithm) + self.training_iteration +=1 + #evaluation results + write_eval_stats(episode_rewards, episode_lengths, self.file_name) + + mean_reward, std_reward = np.mean(episode_rewards), np.std(episode_rewards) + mean_ep_length, std_ep_length = np.mean(episode_lengths), np.std(episode_lengths) + + if self.verbose > 0: + print(f"Eval num_timesteps={self.num_timesteps}, " f"episode_reward={mean_reward:.2f} +/- {std_reward:.2f}") + print(f"Episode length: {mean_ep_length:.2f} +/- {std_ep_length:.2f}") + return True + +#-------------- Custom Classes ------------# + +def parse_args(): + parser = argparse.ArgumentParser(description=__doc__) # docstring at beginning of the file is stored in __doc__ + parser.add_argument('-c', '--config-file', dest='config_file', action='store', default='default_config', + help='Configuration file containing configuration to run experiments. It must be a Python file so config can be given programmatically. There are 2 types of configs - VARIABLE CONFIG across the experiments and STATIC CONFIG across the experiments. \nVARIABLE CONFIGS: The OrderedDicts var_env_configs, var_agent_configs and var_model_configs hold configuration options that are variable for the environment, agent and model across the current experiment. For each configuration option, the option is the key in the dict and its value is a list of values it can take for the current experiment. A Cartesian product of these lists is taken to generate various possible configurations to be run. For example, you might want to vary "delay" for the current experiment. Then "delay" would be a key in var_env_configs dict and its value would be a list of values it can take. Because Ray does not have a common way to address this specification of configurations for its agents, there are a few hacky ways to set var_agent_configs and var_model_configs currently. Please see sample experiment config files in the experiments directory to see how to set the values for a given algorithm. \nSTATIC CONFIGS: env_config, agent_config and model_config are dicts which hold the static configuration for the current experiment as a normal Python dict.') + parser.add_argument('-e', '--exp-name', dest='exp_name', action='store', default='mdpp_default_experiment', + help='The user-chosen name of the experiment. This is used as the prefix of the output files (the prefix also contains config_num if that is provided). It will save stats to 2 CSV files, with the filenames as the one given as argument' + ' and another file with an extra "_eval" in the filename that contains evaluation stats during the training. Appends to existing files or creates new ones if they don\'t exist.') + parser.add_argument('-n', '--config-num', dest='config_num', action='store', default=None, type=int, + help='Used for running the configurations of experiments in parallel. This is appended to the prefix of the output files (after exp_name).' + ' A Cartesian product of different configuration values for the experiment will be taken and ordered as a list and this number corresponds to the configuration number in this list.' + ' Please look in to the code for details.') + # parser.add_argument('-t', '--tune-hps', dest='tune_hps', action='store', default=False, type=bool, + # help='Used for tuning the hyperparameters that can be used for experiments later.' + # ' A Cartesian product of different configuration values for the experiment will be taken and ordered as a list and this number corresponds to the configuration number in this list.' + # ' Please look in to the code for details.') + args = parser.parse_args() + print("Parsed args:", args) + return args + +# Callback to write training stats to CSV file at end of every training iteration +def on_train_result(train_env, training_iteration, filename, config_algorithm): + # Writes every iteration, would slow things down. #hack + fout = open(filename, 'a') #hardcoded + fout.write(str(training_iteration) + ' ' + config_algorithm + ' ') + for config_type, config_dict in var_configs_deepcopy.items(): + for key in config_dict: + if config_type == "env": + if key == 'reward_noise': + fout.write(str(info["result"]["config"]["env_config"]['reward_noise_std']) + ' ') #hack + elif key == 'transition_noise' and info["result"]["config"]["env_config"]["state_space_type"] == "continuous": + fout.write(str(info["result"]["config"]["env_config"]['transition_noise_std']) + ' ') #hack + else: + fout.write(str(info["result"]["config"]["env_config"][key]).replace(' ', '') + ' ') + elif config_type == "agent": + if config_algorithm == 'SAC' and key == "critic_learning_rate": + real_key = "lr" #hack due to Ray's weird ConfigSpaces + fout.write(str(info["result"]["config"]['optimization'][key]).replace(' ', '') + ' ') + elif config_algorithm == 'SAC' and key == "fcnet_hiddens": + #hack due to Ray's weird ConfigSpaces + fout.write(str(info["result"]["config"]["Q_model"][key]).replace(' ', '') + ' ') + else: + fout.write(str(info["result"]["config"][key]).replace(' ', '') + ' ') + elif config_type == "model": + # if key == 'conv_filters': + fout.write(str(info["result"]["config"]["model"][key]).replace(' ', '') + ' ') + + # Write train stats + timesteps_total = info["result"]["timesteps_total"] # also has episodes_total and training_iteration + episode_reward_mean = info["result"]["episode_reward_mean"] # also has max and min + # print("Custom_metrics: ", info["result"]["step_reward_mean"], info["result"]["step_reward_max"], info["result"]["step_reward_min"]) + episode_len_mean = info["result"]["episode_len_mean"] + + fout.write(str(timesteps_total) + ' ' + str(episode_reward_mean) + + ' ' + str(episode_len_mean) + '\n') # timesteps_total always HAS to be the 1st written: analysis.py depends on it + fout.close() + + # print("##### hack_filename: ", hack_filename) + # print(os.getcwd()) + + # We did not manage to find an easy way to log evaluation stats for Ray without the following hack which demarcates the end of a training iteration in the evaluation stats file + hack_filename_eval = stats_file_name + '_eval.csv' + fout = open(hack_filename_eval, 'a') #hardcoded + fout.write('#HACK STRING EVAL' + "\n") + fout.close() + + info["result"]["callback_ok"] = True + +# Used in callback after every episode has ended during evaluation +# replaces: def on_episode_end(info) +def write_eval_stats(episode_rewards, episode_lengths, stats_file_name = ""): + eval_filename = stats_file_name + '_eval.csv' + fout = open(eval_filename, 'a') #hardcoded + for reward_this_episode, length_this_episode in zip(episode_rewards, episode_lengths): + fout.write(str(reward_this_episode) + ' ' + str(length_this_episode) + "\n") + fout.close() + +def deepmerge(a, b, path=None): + '''Merges dict b into dict a + + Based on: https://stackoverflow.com/questions/7204805/how-to-merge-dictionaries-of-dictionaries/7205107#7205107 + ''' + if path is None: path = [] + for key in b: + if key in a: + if isinstance(a[key], dict) and isinstance(b[key], dict): + deepmerge(a[key], b[key], path + [str(key)]) + elif a[key] == b[key]: + pass # same leaf value + else: + raise Exception('Conflict at %s' % '.'.join(path + [str(key)])) + else: + a[key] = b[key] + return a + +def cartesian_prod(args, config): + value_tuples = [] + for config_type, config_dict in config.var_configs.items(): + for key in config_dict: + assert type(config.var_configs[config_type][key]) == list, "var_config should be a dict of dicts with lists as the leaf values to allow each configuration option to take multiple possible values" + value_tuples.append(config.var_configs[config_type][key]) + + cartesian_product_configs = list(itertools.product(*value_tuples)) + print("Total number of configs. to run:", len(cartesian_product_configs)) + + if args.config_num is None: + pass + else: + cartesian_product_configs = [cartesian_product_configs[args.config_num]] + + return cartesian_product_configs + +def process_dictionaries(config, current_config, var_env_configs, var_agent_configs, var_model_configs): + algorithm = config.algorithm + agent_config = config.agent_config + model_config = config.model_config + env_config = config.env_config + + for config_type, config_dict in config.var_configs.items(): + for key in config_dict: + # if config_type == "env_config": # There is a dummy seed in the env_config because it's not used in the environment. It implies a different seed for the agent on every launch as the seed for Ray is not being set here. I faced problems with Ray's seeding process. + if config_type == "env": + if key == 'reward_noise': + reward_noise_ = current_config[list(var_env_configs).index(key)] # this works because env_configs are 1st in the OrderedDict + env_config["env_config"][key] = lambda a: a.normal(0, reward_noise_) + env_config["env_config"]['reward_noise_std'] = reward_noise_ #hack Needed to be able to write scalar value of std dev. to stats file instead of the lambda function above ###TODO Could remove the hack by creating a class for the noises and changing its repr() + elif key == 'transition_noise' and env_config["env_config"]["state_space_type"] == "continuous": + transition_noise_ = current_config[list(var_env_configs).index(key)] + env_config["env_config"][key] = lambda a: a.normal(0, transition_noise_) + env_config["env_config"]['transition_noise_std'] = transition_noise_ #hack + else: + env_config["env_config"][key] = current_config[list(var_env_configs).index(key)] + + elif config_type == "agent": + num_configs_done = len(list(var_env_configs)) + if algorithm == 'SAC' and key == 'critic_learning_rate': #hack + value = current_config[num_configs_done + list(config.var_configs[config_type]).index(key)] + agent_config['optimization'] = { + key: value, + 'actor_learning_rate': value, + 'entropy_learning_rate': value, + } + elif algorithm == 'SAC' and key == 'fcnet_hiddens': #hack + agent_config['Q_model'] = { + key: current_config[num_configs_done + list(config.var_configs[config_type]).index(key)], + "fcnet_activation": "relu", + } + agent_config['policy_model'] = { + key: current_config[num_configs_done + list(config.var_configs[config_type]).index(key)], + "fcnet_activation": "relu", + } + else: + agent_config[key] = current_config[num_configs_done + list(config.var_configs[config_type]).index(key)] + + elif config_type == "model": + num_configs_done = len(list(var_env_configs)) + len(list(var_agent_configs)) + model_config["model"][key] = current_config[num_configs_done + list(config.var_configs[config_type]).index(key)] + + #hacks begin: + if model_config["model"]["use_lstm"]: + model_config["model"]["max_seq_len"] = env_config["env_config"]["delay"] + env_config["env_config"]["sequence_length"] + 1 + + if algorithm == 'DDPG': ###TODO Find a better way to enforce these?? + agent_config["actor_lr"] = agent_config["critic_lr"] + agent_config["actor_hiddens"] = agent_config["critic_hiddens"] + elif algorithm == 'TD3': + agent_config["target_noise_clip"] = agent_config["target_noise_clip"] * agent_config["target_noise"] + + # else: #if algorithm == 'SAC': + if env_config["env_config"]["state_space_type"] == 'continuous': + env_config["env_config"]["action_space_dim"] = env_config["env_config"]["state_space_dim"] + + return agent_config, model_config, env_config, algorithm + +def act_fnc_from_name(key): + if(key == "tanh"): + return nn.Tanh + elif(key == "sigmoid"): + return nn.Sigmoid + elif(key == "leakyrelu"): + return nn.LeakyReLU + else: #default + return nn.ReLU + +def process_agent_dict(algorithm, agent_config, model_config, env): + policy_kwargs = {} + if algorithm == 'DQN': + #change keys in dictionaries to something baselines understands + valid_keys = ['buffer_size', "learning_starts", "tau","gamma", "train_freq", "gradient_steps", "n_episodes_rollout", "target_update_interval","exploration_fraction","exploration_initial_eps","exploration_final_eps","max_grad_norm","tensorboard_log","learning_rate","batch_size","target_update_interval","lr_schedule"] + + exchange_keys = [ + ('lr','learning_rate'), + ('train_batch_size', 'batch_size'), + ('target_network_update_freq','target_update_interval')] + for key_tuple in exchange_keys: + old_key, new_key = key_tuple + if(old_key in agent_config): + agent_config[new_key] = agent_config.pop(old_key) + #remove keys from dictionary which are not configurable by baselines + for key in list(agent_config.keys()): + if( key not in valid_keys ): + agent_config.pop(key) + + #-------------- Model configuration ------------# + #decide whether to use cnn or mlp, taken from ray code.. + # Discrete/1D obs-spaces. + if isinstance(env.observation_space, gym.spaces.Discrete) or \ + len(env.observation_space.shape) <= 2: + feat_ext ="MlpPolicy" + else:# Default Conv2D net. + feat_ext = "CnnPolicy" + agent_config['policy'] = feat_ext + cnn_config = {} + + if(feat_ext == "MlpPolicy"): #mlp config + if("fcnet_activation" in model_config['model']): + policy_kwargs['activation_fn'] = act_fnc_from_name( model_config['model']["fcnet_activation"]) + if("fcnet_hiddens" in model_config['model']): + policy_kwargs['net_arch'] = model_config['model']["fcnet_hiddens"] + #this is to create a custom CNN since there's no implementation currently + else: #cnn config + policy_kwargs['net_arch'] = model_config['model']["fcnet_hiddens"] + if("conv_activation" in model_config['model'] ): + cnn_config["activation_fn"] = act_fnc_from_name( model_config['model']["conv_activation"] ) + if("conv_filters" in model_config['model'] ): + cnn_config["cnn_layers"] = model_config['model']["conv_filters"] + + #custom + if( feat_ext == "CnnPolicy"): + policy_kwargs['features_extractor_class'] = VisionNet + policy_kwargs["features_extractor_kwargs"] = cnn_config + + #add policy arguments to agent configuration + if('lr_schedule'in agent_config.keys()): #schedule is part of model instead of agent in baselines + policy_kwargs['lr_schedule'] = agent_config['lr_schedule'] + agent_config['policy_kwargs'] = policy_kwargs + + return agent_config + +def main(args): + #print("Config file", os.path.abspath(args.config_file)) # 'experiments/dqn_seq_del.py' + if args.config_file[-3:] == '.py': + args.config_file = args.config_file[:-3] + + config_file_path = os.path.abspath('/'.join(args.config_file.split('/')[:-1])) + print("config_file_path:", config_file_path) + + sys.path.insert(1, config_file_path) #hack + config = importlib.import_module(args.config_file.split('/')[-1], package=None) + print("Number of seeds for environment:", config.num_seeds) + print("Configuration numbers that will be run:", "all" if args.config_num is None else args.config_num) + + args.exp_name = os.path.abspath(args.exp_name) + if args.config_num is None: + stats_file_name = args.exp_name + else: + stats_file_name = args.exp_name + '_' + str(args.config_num) + print("Stats file being written to:", stats_file_name) + + #------------------------- Variable configurations ----------------------------# + var_configs_deepcopy = copy.deepcopy(config.var_configs) + + if "env" in config.var_configs: + var_env_configs = config.var_configs["env"] #hack + else: + var_env_configs = [] + if "agent" in config.var_configs: + var_agent_configs = config.var_configs["agent"] #hack + else: + var_agent_configs = [] + if "model" in config.var_configs: + var_model_configs = config.var_configs["model"] #hack + else: + var_model_configs = [] + + print('# Algorithm, state_space_size, action_space_size, delay, sequence_length, reward_density, make_denser, terminal_state_density, transition_noise, reward_noise ') + + configs_to_print = '' + for config_type, config_dict in var_configs_deepcopy.items(): + if config_type == 'env': + for key in config_dict: + configs_to_print += str(config_dict[key]) + ', ' + + print(config.algorithm, configs_to_print) + + #----------------- Write headers to csv file --------------------# + hack_filename = stats_file_name + '.csv' + fout = open(hack_filename, 'a') #hardcoded + fout.write('# training_iteration, algorithm, ') + for config_type, config_dict in var_configs_deepcopy.items(): + for key in config_dict: + fout.write(key + ', ') + fout.write('timesteps_total, episode_reward_mean, episode_len_mean\n') + fout.close() + + #---------- Compute cartesian product of configs ----------------# + start = time.time() + cartesian_product_configs = cartesian_prod(args, config) + + #------------ Run every configuration ------------------ # + pp = pprint.PrettyPrinter(indent=4) + for current_config in cartesian_product_configs: + #------------ Dictionaries setup ------------------ # + agent_config, model_config, env_config, algorithm = process_dictionaries(config, current_config, var_env_configs, var_agent_configs, var_model_configs) #modify to match baselines syntax + + #------------ Env init ------------------ # + env = gym.make(env_config['env'],**env_config['env_config']) + env = Monitor(env, None) + + #Evaluation environment + #limit max timesteps in evaluation = horizon + eval_horizon = 100 + eval_env = gym.make(env_config['env'],**env_config['env_config']) + eval_env.spec.tags['wrapper_config.TimeLimit.max_episode_steps'] = eval_horizon + eval_env = TimeLimit(eval_env, max_episode_steps = eval_horizon) #horizon + print("Env config:",) + pp.pprint(env_config) + + #------------ Agent init ------------------ # + # Create the agent + timesteps_per_iteration = agent_config['timesteps_per_iteration'] + agent_config_p = process_agent_dict(algorithm, agent_config.copy(), model_config, env) + if config.algorithm == 'DQN': + model = DQN(env = env, **agent_config_p, verbose=1) + elif config.algorithm == 'DDPG': #hack + model = DDPG(env = env, **agent_config_p) + else: #'SAC' + model = SAC(env = env, **agent_config_p) + + #------------ evaluation / training ------------------ # + if env_config["env"] in ["HopperWrapper-v3", "HalfCheetahWrapper-v3"]: #hack + timesteps_total = 500000 + else: + if algorithm == 'DQN': + timesteps_total = 20000 + elif algorithm == 'A3C': #hack + timesteps_total = 150000 + else: #if algorithm == 'DDPG': #hack + timesteps_total = 20000 + + #Define evaluation + evaluation_interval = 1 #every x training iterations + eval_frequency = timesteps_per_iteration * evaluation_interval + eval_callback = CustomCallback(eval_env, n_eval_episodes=10, eval_freq=eval_frequency, \ + deterministic=True, file_name = stats_file_name, config_algorithm = algorithm) + #Train + model.learn(callback= eval_callback, total_timesteps = timesteps_total) + rewards = env.get_episode_rewards() + espisode_lengths = env.get_episode_lengths() + episode_times = env.get_episode_times() + total_steps = env.get_total_steps() + # Evaluate the agent at the end of training? + #mean_reward, std_reward = evaluate_policy(model, model.get_env(), n_eval_episodes=10) + + end = time.time() + print("No. of seconds to run:", end - start) + + +if __name__ == '__main__': + args = parse_args() + main(args) \ No newline at end of file diff --git a/test_cave_analysis.py b/test_cave_analysis.py deleted file mode 100644 index 863137d..0000000 --- a/test_cave_analysis.py +++ /dev/null @@ -1,33 +0,0 @@ -from cave.cavefacade import CAVE -from mdp_playground.analysis.mdpp_to_cave import MDPPToCave -import os - -files_dir = "/mnt/484A4CAB4A4C9798/GoogleDrive/Maestria-Drive/HiWi/mdp_files/" #baselines" -experiments = { -# "a3c_seq" : "%s/a3c_seq/"%files_dir, -# "a3c_lstm_seq" : "%s/a3c_lstm_seq/"%files_dir, -# "a3c_del" : "%s/a3c_del/"%files_dir, -# "a3c_lstm_del" : "%s/a3c_lstm_del/"%files_dir, - "dqn_seq_del": files_dir -} - -#The converted mdpp csvs will be stored in output_dir -output_dir = "../mdpp_to_cave" -mdpp_cave = MDPPToCave(output_dir) -for exp_name, v in experiments.items(): - dir_name, _ = os.path.split(v) - cave_input_file = mdpp_cave.to_bohb_results(dir_name, exp_name) - print(cave_input_file) -# Similarly, as an example, cave will ouput it's results -# to the same directory as cave's input files - -cave_results = os.path.join(cave_input_file, "out") -cave = CAVE(folders = [cave_input_file], - output_dir = cave_results, - ta_exec_dir = [cave_input_file], - file_format = "BOHB", - show_jupyter=True, - ) -# cave.performance_table() -# cave.local_parameter_importance() -cave.cave_fanova() \ No newline at end of file From 99202befb4fea8464e43e058de46f8df15a5ac16 Mon Sep 17 00:00:00 2001 From: JessicaBorja Date: Thu, 13 May 2021 19:20:43 +0200 Subject: [PATCH 08/22] cfg_processor --- .../config_processor/config_processor.py | 328 ++++++++++++++++++ 1 file changed, 328 insertions(+) create mode 100644 mdp_playground/config_processor/config_processor.py diff --git a/mdp_playground/config_processor/config_processor.py b/mdp_playground/config_processor/config_processor.py new file mode 100644 index 0000000..523bc21 --- /dev/null +++ b/mdp_playground/config_processor/config_processor.py @@ -0,0 +1,328 @@ + +from os import stat +from numpy.core.fromnumeric import var +from ray.tune.registry import register_env +from .baselines_processor import agent_to_baselines, model_to_policy_kwargs +import copy + +mujoco_envs = ["HalfCheetahWrapper-v3", "HopperWrapper-v3", "PusherWrapper-v2", "ReacherWrapper-v2"] + +def get_grid_of_configs(var_configs): + ''' + var_configs: dict of dicts of lists as values + A dict of dicts with lists as the leaf values to allow each configuration option to take multiple possible values. + ''' + value_tuples = [] + + # TODO Currently, the var_configs dict is nested, might want to make it single level. However, the config dicts used in Ray are nested, so keep it like this for now. Further, the 2nd level division chosen for configs currently, i.e., env, agent, model is a bit arbitrary, but better like this since it can be compliant with Ray and other frameworks and additional processing can take place in framework_specific_processing() below. + for config_type, config_dict in var_configs.items(): + for key in config_dict: + assert type(var_configs[config_type][key]) == list, "var_configs should be a dict of dicts with lists as the leaf values to allow each configuration option to take multiple possible values" + value_tuples.append(var_configs[config_type][key]) + + import itertools + if len(value_tuples) == 0: + cartesian_product_configs = [] # Edge case, else it'd become [()]. + else: + cartesian_product_configs = list(itertools.product(*value_tuples)) + + print("Total number of configs. to run:", len(cartesian_product_configs)) + + grid_of_configs = [] + + for enum_conf_1, current_config in enumerate(cartesian_product_configs): + env_config = {"env": {}} + model_config = {"model": {}} + agent_config = {"agent": {}} + + for config_type, config_dict in var_configs.items(): + for key in config_dict: + # if config_type == "env_config": # There is a dummy seed in the env_config because it's not used in the environment. It implies a different seed for the agent on every launch as the seed for Ray is not being set here. I faced problems with Ray's seeding process. + if config_type == "env": + env_config["env"][key] = current_config[list(var_configs["env"]).index(key)] + + elif config_type == "agent": #hack All these are hacks to get around different limitations + num_configs_done = len(list(var_configs["env"])) + agent_config["agent"][key] = current_config[num_configs_done + list(var_configs[config_type]).index(key)] + + elif config_type == "model": + num_configs_done = len(list(var_configs["env"])) + len(list(var_agent_configs)) + model_config["model"][key] = current_config[num_configs_done + list(var_configs[config_type]).index(key)] + + combined_config = {**agent_config, **model_config, **env_config} + + grid_of_configs.append(combined_config) + + return grid_of_configs + + + +def combined_processing(*static_configs, varying_configs, framework='ray', algorithm): + ''' + varying_configs is a dict of dicts with structure: { + } + ''' + # print(len(configs)) + # print(type(configs)) + # print(type(*configs)) + + # Pre-processing common to frameworks: + for i, varying_config in enumerate(varying_configs): + + ###IMP This needs to be done before merging because otherwise varying_config["env"] clashes with + varying_config = {"env_config": varying_config["env"], **varying_config["agent"], "model": varying_config["model"]} + varying_configs[i] = varying_config + + # Ray specific pre-processing + if framework.lower() == 'ray': + ... + + # Stable Baselines specific pre-processing + elif framework.lower() == 'stable_baselines': + env_cfg, agent_cfg, model_cfg, eval_cfg = static_configs + static_configs = list(static_configs) + # Change variable configuration keys + for i, cfg_dict in enumerate(varying_configs): + var_cfg = cfg_dict.copy() + var_env_cfg = var_cfg.pop('env_config') + var_model_cfg = var_cfg.pop('model') + cfg = {"model": var_model_cfg, + "agent": var_cfg} + # make agent and model static empty configs + curr_cfg = (algorithm, {}, {}, cfg) + # algorithm, agent_config, model_config, var_configs + _, _, var_agent_configs, var_model_configs =\ + agent_to_baselines(curr_cfg) + varying_configs[i] = {} + varying_configs[i]["env_config"] = var_env_cfg + varying_configs[i]["model"] = var_model_configs + varying_configs[i]["agent"] = var_agent_configs + # Change static configuration keys + # Make variable empty configs + curr_cfg = (algorithm, agent_cfg, model_cfg, {}) + agent_config, model_config, _, _ = agent_to_baselines(curr_cfg) + static_configs = (env_cfg, + {"agent": agent_config}, + {"model": model_config}, + eval_cfg) + static_configs = tuple(static_configs) + else: + raise ValueError("Framework passed was not a valid option. It was: " + framework + ". Available options are: ray and stable_baselines.") + + # Merge all configs into one + final_configs = [] + for i in range(len(varying_configs)): + # for in range(len()): + static_configs_copy = copy.deepcopy(static_configs) + merged_conf = deepmerge_multiple_dicts(*static_configs_copy, varying_configs[i]) + final_configs.append(merged_conf) # varying_configs, env_config, agent_config, eval_config + + # Post-processing common to frameworks: + for i, final_config in enumerate(final_configs): + if final_configs[i]["env"] in mujoco_envs: + if "time_unit" in final_configs[i]["env_config"]: #hack This is needed so that the environment runs the same amount of seconds of simulation, even though episode steps are different. + final_configs[i]["horizon"] /= final_configs[i]["env_config"]["time_unit"] + final_configs[i]["horizon"] = int(final_configs[i]["horizon"]) + + final_configs[i]["learning_starts"] /= final_configs[i]["env_config"]["time_unit"] + final_configs[i]["learning_starts"] = int(final_configs[i]["learning_starts"]) + + final_configs[i]["timesteps_per_iteration"] /= final_configs[i]["env_config"]["time_unit"] + final_configs[i]["timesteps_per_iteration"] = int(final_configs[i]["timesteps_per_iteration"]) + + final_configs[i]["evaluation_config"]["horizon"] /= final_configs[i]["env_config"]["time_unit"] + final_configs[i]["evaluation_config"]["horizon"] = int(final_configs[i]["evaluation_config"]["horizon"]) + + final_configs[i]["train_batch_size"] *= final_configs[i]["env_config"]["time_unit"] # this is needed because Ray (until version 0.8.6 I think) fixes the ratio of number of samples trained/number of steps sampled in environment + final_configs[i]["train_batch_size"] = int(final_configs[i]["train_batch_size"]) + + # hack Common #mujoco wrapper to allow Mujoco envs to be wrapped by MujocoEnvWrapper (which fiddles with lower-level Mujoco stuff) and then by GymEnvWrapper which is more general and basically adds dimensions from MDPP which are common to discrete and continuous environments + # if final_configs[i]["env"] in mujoco_envs: + + # default settings for #timesteps_total + if final_configs[i]["env"] in ["HalfCheetahWrapper-v3"]: #hack + timesteps_total = 3000000 + + from mdp_playground.envs.mujoco_env_wrapper import get_mujoco_wrapper #hack + from gym.envs.mujoco.half_cheetah_v3 import HalfCheetahEnv + wrapped_mujoco_env = get_mujoco_wrapper(HalfCheetahEnv) + register_env("HalfCheetahWrapper-v3", lambda config: create_gym_env_wrapper_mujoco_wrapper(config, wrapped_mujoco_env)) + + elif final_configs[i]["env"] in ["HopperWrapper-v3"]: #hack + timesteps_total = 1000000 + + from mdp_playground.envs.mujoco_env_wrapper import get_mujoco_wrapper #hack + from gym.envs.mujoco.hopper_v3 import HopperEnv + wrapped_mujoco_env = get_mujoco_wrapper(HopperEnv) + register_env("HopperWrapper-v3", lambda config: create_gym_env_wrapper_mujoco_wrapper(config, wrapped_mujoco_env)) + + elif final_configs[i]["env"] in ["PusherWrapper-v2"]: #hack + timesteps_total = 500000 + + from mdp_playground.envs.mujoco_env_wrapper import get_mujoco_wrapper #hack + from gym.envs.mujoco.pusher import PusherEnv + wrapped_mujoco_env = get_mujoco_wrapper(PusherEnv) + register_env("PusherWrapper-v2", lambda config: create_gym_env_wrapper_mujoco_wrapper(config, wrapped_mujoco_env)) + + elif final_configs[i]["env"] in ["ReacherWrapper-v2"]: #hack + timesteps_total = 500000 + + from mdp_playground.envs.mujoco_env_wrapper import get_mujoco_wrapper #hack + from gym.envs.mujoco.reacher import ReacherEnv + wrapped_mujoco_env = get_mujoco_wrapper(ReacherEnv) + register_env("ReacherWrapper-v2", lambda config: create_gym_env_wrapper_mujoco_wrapper(config, wrapped_mujoco_env)) + + elif final_configs[i]["env"] in ["GymEnvWrapper-Atari"]: #hack + if "AtariEnv" in final_configs[i]["env_config"]: + timesteps_total = 10_000_000 + + else: + if algorithm == 'DQN': + timesteps_total = 20000 + elif algorithm == 'A3C': # hack + timesteps_total = 150000 + else: # if algorithm == 'DDPG': #hack + timesteps_total = 20000 + + if final_configs[i]["env"] in mujoco_envs: + if "time_unit" in final_configs[i]["env_config"]: #hack This is needed so that the environment runs the same amount of seconds of simulation, even though episode steps are different. + timesteps_total /= final_configs[i]["env_config"]["time_unit"] + timesteps_total = int(timesteps_total) + + final_configs[i]["timesteps_total"] = timesteps_total + + # Post-processing for Ray: + if framework.lower() == 'ray': + for i in range(len(final_configs)): + # for config_type in varying_config: + for key in final_configs[i]: + value = final_configs[i][key] + + if algorithm == 'SAC': + if key == 'critic_learning_rate': # hack + final_configs[i]['optimization'] = { + key: value, + 'actor_learning_rate': value, + 'entropy_learning_rate': value, + } + if key == 'fcnet_hiddens': #hack + final_configs[i]['Q_model'] = { + key: value, + "fcnet_activation": "relu", + } + final_configs[i]['policy_model'] = { + key: value, + "fcnet_activation": "relu", + } + + if algorithm == 'DDPG': ###TODO Find a better way to enforce these?? Especially problematic for TD3 because then more values for target_noise_clip are witten to CSVs than actually used during HPO but for normal (non-HPO) runs this needs to be not done. + if key == "critic_lr": + final_configs[i]["actor_lr"] = value + if key == "critic_hiddens": + final_configs[i]["actor_hiddens"] = value + if algorithm == 'TD3': + if key == "target_noise_clip_relative": + final_configs[i]["target_noise_clip"] = final_configs[i]["target_noise_clip_relative"] * final_configs[i]["target_noise"] + del final_configs[i]["target_noise_clip_relative"] #hack have to delete it otherwise Ray will crash for unknown config param. + + elif key == "model": + for key_2 in final_configs[i][key]: + if key_2 == "use_lstm": + final_configs[i][key][key_2]["max_seq_len"] = final_configs[i]["env"]["env_config"]["delay"] + final_configs[i]["env"]["env_config"]["sequence_length"] + 1 + + # Post-processing for Stable Baselines: + elif framework.lower() == 'stable_baselines': + ts_k = "timesteps_per_iteration" + for i, config in enumerate(final_configs): + model_config = config["model"] + use_cnn = False + if("feature_extraction" in config["agent"]["policy_kwargs"]): + if config["agent"]["policy_kwargs"]["feature_extraction"] == "cnn": + use_cnn = True + feat_ext = 'mlp' if config["env_config"]["state_space_type"] == "discrete" \ + and not use_cnn else 'cnn' + policy_kwargs, use_lstm = \ + model_to_policy_kwargs(feat_ext, model_config) # return policy_kwargs + config["agent"]["policy_kwargs"].update(policy_kwargs) + if(ts_k in config["agent"]): + # this is not part of baselines parameters, need to separate + timesteps_per_iteration = config["agent"].pop(ts_k) + config[ts_k] = timesteps_per_iteration + else: + config[ts_k] = 1000 # default + config["use_lstm"] = use_lstm + + return final_configs + + +###TODO **extra_config} + +def create_gym_env_wrapper_mujoco_wrapper(config, wrapped_mujoco_env): + '''Creates a GymEnvWrapper around a MujocoEnvWrapper + ''' + from mdp_playground.envs.gym_env_wrapper import GymEnvWrapper + me = wrapped_mujoco_env(**config) + gew = GymEnvWrapper(me, **config) ##IMP Had initially thought to put this config in config["GymEnvWrapper"] but because of code below which converts var_env_configs to env_config, it's best to leave those configs as top level configs in the dict! + return gew + + +def deepmerge_multiple_dicts(*configs): + ''' + ''' + merged_configs = {} + for i in range(len(configs)): + # print(i) + merged_configs = deepmerge(merged_configs, configs[i]) + + return merged_configs + + +from functools import reduce +def deepmerge(a, b, path=None): + '''Merges dict b into dict a + Based on: https://stackoverflow.com/questions/7204805/how-to-merge-dictionaries-of-dictionaries/7205107#7205107 + ''' + if path is None: path = [] + for key in b: + if key in a: + if isinstance(a[key], dict) and isinstance(b[key], dict): + deepmerge(a[key], b[key], path + [str(key)]) + elif a[key] == b[key]: + pass # same leaf value + else: + raise Exception('Conflict at %s' % '.'.join(path + [str(key)])) + else: + a[key] = b[key] + return a + + +import mdp_playground +from mdp_playground.envs import RLToyEnv +from ray.tune.registry import register_env +register_env("RLToy-v0", lambda config: RLToyEnv(**config)) + +def create_gym_env_wrapper_atari(config): + from gym.envs.atari import AtariEnv + from mdp_playground.envs.gym_env_wrapper import GymEnvWrapper + ae = AtariEnv(**config["AtariEnv"]) + gew = GymEnvWrapper(ae, **config) ##IMP Had initially thought to put this config in config["GymEnvWrapper"] but because of code below which converts var_env_configs to env_config, it's best to leave those configs as top level configs in the dict! + return gew + +register_env("GymEnvWrapper-Atari", lambda config: create_gym_env_wrapper_atari(config)) + + +def create_gym_env_wrapper_frame_stack_atari(config): #hack ###TODO remove? + '''When using frameStack GymEnvWrapper should wrap AtariEnv using wrap_deepmind_ray and therefore this function sets "wrap_deepmind_ray": True and 'frame_skip': 1 inside config so as to keep config same as for create_gym_env_wrapper_atari above and reduce manual errors when switching between the 2. + ''' + config["wrap_deepmind_ray"] = True #hack + config["frame_skip"] = 1 #hack + from gym.envs.atari import AtariEnv + from mdp_playground.envs.gym_env_wrapper import GymEnvWrapper + import gym + game = config["AtariEnv"]["game"] + game = ''.join([g.capitalize() for g in game.split('_')]) + ae = gym.make('{}NoFrameskip-v4'.format(game)) + gew = GymEnvWrapper(ae, **config) ##IMP Had initially thought to put this config in config["GymEnvWrapper"] but because of code below which converts var_env_configs to env_config, it's best to leave those configs as top level configs in the dict! + return gew + +register_env("GymEnvWrapperFrameStack-Atari", lambda config: create_gym_env_wrapper_frame_stack_atari(config)) \ No newline at end of file From 413448fabb1a09b5dc3a323b2771cc3167150ee9 Mon Sep 17 00:00:00 2001 From: JessicaBorja Date: Thu, 13 May 2021 19:24:34 +0200 Subject: [PATCH 09/22] processor changes --- .../config_processor/baselines_processor.py | 505 +++++++++++++ ...g_processor.py => config_processor_old.py} | 0 run_experiments.py | 2 +- run_experiments_baselines.py | 685 ++---------------- 4 files changed, 558 insertions(+), 634 deletions(-) create mode 100644 mdp_playground/config_processor/baselines_processor.py rename mdp_playground/config_processor/{config_processor.py => config_processor_old.py} (100%) diff --git a/mdp_playground/config_processor/baselines_processor.py b/mdp_playground/config_processor/baselines_processor.py new file mode 100644 index 0000000..029e119 --- /dev/null +++ b/mdp_playground/config_processor/baselines_processor.py @@ -0,0 +1,505 @@ + +from stable_baselines.common.noise import NormalActionNoise, OrnsteinUhlenbeckActionNoise +import gym +from stable_baselines.common.tf_layers import conv, linear, conv_to_fc, lstm +import tensorflow as tf +import numpy as np +import stable_baselines as sb +from typing import Any, Dict, List, Optional, Union +from stable_baselines.common.vec_env import DummyVecEnv, VecEnv, sync_envs_normalization +from stable_baselines import DQN, DDPG, SAC, A2C, TD3 + + +# change config.agent_config, +# config.var_model_config +# config.var_agent_config to baselines framework +def agent_to_baselines(config): + policy_kwargs = {} + algorithm, agent_config, model_config, var_configs = config + var_agent_configs, var_model_configs = {}, {} + if("agent" in var_configs): + var_agent_configs = var_configs["agent"] + if("model" in var_configs): + var_model_configs = var_configs["model"] + + + valid_keys = ["gamma", "buffer_size", "batch_size", "learning_starts", + "timesteps_per_iteration"] # common + agent_to_model = [] # none + # Check correct keys for each algorithm + if algorithm == 'DQN': + # change keys in dictionaries to something baselines understands + valid_keys += ["exploration_fraction", "exploration_final_eps", + "exploration_initial_eps", + "train_freq", "double_q", + "prioritized_replay", "prioritized_replay_alpha", + "param_noise", "learning_rate", + "target_network_update_freq"] + + exchange_keys = [('noisy', 'param_noise'), + ('lr', 'learning_rate'), + ('train_batch_size', 'batch_size'), + ("rollout_fragment_length", "train_freq")] + # Move dueling to policy parameters + agent_to_model += [("dueling", "dueling")] + elif algorithm == "DDPG": + # memory_policy can be used to select PER + # random_exploration, param_noise, action_noise parameters aditional + valid_keys += ["critic_lr", "actor_lr", "tau","critic_l2_reg",\ + "clip_norm", "nb_rollout_steps", "nb_train_steps"] + valid_keys.remove("learning_starts") # For some reason it's the only one that does not have this implemented + exchange_keys = [ + ('rollout_fragment_length','nb_rollout_steps'), + ("l2_reg", "critic_l2_reg"), + ("grad_norm_clipping", "clip_norm"), + ('train_batch_size', 'batch_size')] + # Because of how DDPG is implemented it will perform 100 rollout steps and then 50 train steps + # This needs to be changed s.t. it does one rollout step and one training step + agent_config["nb_rollout_steps"] = 1 + agent_config["nb_train_steps"] = 1 + agent_to_model+=[("actor_hiddens", "layers"),("critic_hiddens", "layers")]#cannot specify different nets + # SPECIAL CASE, learning rates SHOULD NOT be none :c + for key in ["critic_lr", "actor_lr"]: + key_not_none = agent_config.get(key) + if (key in agent_config): + if(not key_not_none): #key==none + agent_config.pop(key) #remove to get default value + + elif algorithm == "TD3": + # memory_policy can be used to select PER; policy is always smoothened + # random_exploration, param_noise, action_noise parameters aditional + valid_keys += ["learning_rate", "policy_delay","tau","train_freq","gradient_steps",\ + "target_policy_noise","target_noise_clip","action_noise"] + exchange_keys = [ + ("target_noise", "target_policy_noise"), + ("critic_lr", "learning_rate"), + ("actor_lr", "learning_rate"), + ('train_batch_size', 'batch_size')] + agent_to_model += [("actor_hiddens", "layers"),( "critic_hiddens", "layers")] + # SPECIAL CASE, learning rates SHOULD NOT be none :c + for key in ["critic_lr, actor_lr"]: + key_not_none = agent_config.get(key) + if (key in agent_config): + if(not key_not_none): + agent_config.pop(key) # remove to get default value + # Because of how TD3 is implemented it will perform 100 grad steps every 100 steps + # This needs to be changed s.t. it does one rollout step and one training step + agent_config["train_freq"] = 1 + agent_config["gradient_steps"] = 1 + # s.t. it clips actions between[-1,1] + agent_config["action_noise"] = NormalActionNoise(mean=0, sigma=0) + elif algorithm == "SAC": + valid_keys += ["learning_rate", "tau", "ent_coef", "train_freq", + "target_update_interval", "clip_norm", "target_entropy"] + exchange_keys = [ + ("rollout_fragment_length","train_freq"), + ("entropy_learning_rate","learning_rate"), # same learning rate for + ("critic_learning_rate", "learning_rate"), # entropy + ("actor_learning_rate", "learning_rate"), # actor and critic + ("target_network_update_freq","target_update_interval"), + ("grad_norm_clipping", "clip_norm"), + ('train_batch_size', 'batch_size')] + agent_to_model += [("fcnet_hiddens", "layers")] + # -------- Add init entropy coef ------------# + if("initial_alpha" in agent_config.keys()): + agent_config["ent_coef"] = "auto_%.3f"%agent_config["initial_alpha"] #idk why but that's how baselines initializes this thing.. + agent_config.pop("initial_alpha") + # var agent configs initial_alpha + # idk why but that's how baselines initializes this thing.. + if(var_agent_configs): + if("initial_alpha" in var_agent_configs): + var_agent_configs["ent_coef"] = ["auto_%.3f"%coef for coef in var_agent_configs["initial_alpha"]] + var_agent_configs.pop("initial_alpha") + # ----------- special case ---------# + # should be at least one + if("target_network_update_freq" in agent_config): + key_val = agent_config["target_network_update_freq"] + agent_config["target_network_update_freq"] = 1 if key_val <= 0 else key_val + # -------- Take things out of optimization ------------# + # Special case: Optimization + if("optimization" in agent_config): + for k in agent_config["optimization"].keys(): + key_value = agent_config["optimization"][k] + if(key_value): # not none + agent_config[k] = key_value + # -------- Take things out of Q-model and policy_model ------------# + # Can only specify one model for everything + for move_key in ["Q_model", "policy_model"]: + if(move_key in model_config): + if("model" not in model_config): # init + model_config["model"] = {} + for k in model_config[move_key].keys(): + model_config["model"][k] = model_config[move_key][k] + model_config.pop(move_key) # Remove from model_config + else: #A2C + algorithm = "A2C" + valid_keys += ["learning_rate","vf_coef", "ent_coef","max_grad_norm"] #"lr_schedule" cannot be none + exchange_keys = [ + ("vf_loss_coeff","vf_coef"), + ("entropy_coeff","ent_coef"), + ("lr", "learning_rate"), + ("grad_clip", "max_grad_norm")] + + # -------- Change keys from Agent to Model dict when needed--------# + for key_tuple in agent_to_model: + old_key, new_key = key_tuple + # -------- Agent config --------# + key_exists = agent_config.get(old_key) + if key_exists: # If key exists and is not none + policy_kwargs[new_key] = agent_config.pop(old_key) # Move key to model config + # #-------- Var agent config --------# + key_exists = var_agent_configs.get(old_key) + if key_exists: # If key exists and is not none + var_model_configs[new_key] = var_agent_configs.pop(old_key) # Move key to model config + + if('fcnet_hiddens' in agent_config.keys()): + policy_kwargs['layers'] = agent_config['fcnet_hiddens'] + agent_config.pop('fcnet_hiddens') + + # -------- Agent config --------# + # change agent keys + for key_tuple in exchange_keys: + old_key, new_key = key_tuple + # -------- Agent config --------# + if(old_key in agent_config): + agent_config[new_key] = agent_config.pop(old_key) + # -------- Var agent config --------# + if(old_key in var_agent_configs): + var_agent_configs[new_key] = var_agent_configs.pop(old_key) + + # remove keys from dictionary which are not configurable by baselines + for key in list(agent_config.keys()): + if(key not in valid_keys): # delete invalid keys + agent_config.pop(key) + + # -------- Var agent config --------# + # remove keys from dictionary which are not configurable by baselines + for key in list(var_agent_configs.keys()): + if(key not in valid_keys):#delete invalid keys + var_agent_configs.pop(key) + + # ----------- Model config ----------------# + valid_keys = ["act_fun", "net_arch", "feature_extractor", "layers", "use_lstm","n_lstm"] + exchange_keys = [("fcnet_activation", "act_fun"), + ("conv_activation", "act_fun"), + ("actor_hidden_activation", "act_fun"), + ("actor_hidden_activation", "act_fun"), + ("fcnet_hiddens", "layers"), + ("actor_hiddens", "layers"), + ("critic_hiddens","layers"), + ("conv_filters", "net_arch"), + ("lstm_cell_size","n_lstm")] + + # change keys + feat_ext = 'mlp' + for key_tuple in exchange_keys: + old_key, new_key = key_tuple + # -------- model config --------# + if("model" in model_config): + if(old_key in model_config["model"]): + if(old_key == 'conv_filters'): + feat_ext = 'cnn' + model_config["model"][new_key] = model_config["model"].pop(old_key) + + # -------- Var model config --------# + if(old_key in var_model_configs): + if(old_key == 'conv_filters'): + feat_ext = 'cnn' + var_model_configs[new_key] = var_model_configs.pop(old_key) + + # remove invalid keys + if("model" in model_config): + for key in list(model_config["model"].keys()): + if(key not in valid_keys): + model_config["model"].pop(key) + + # -------- Var model config - delete invalid keys -------# + for key in list(var_model_configs.keys()): + if(key not in valid_keys): + var_model_configs.pop(key) + + # -------- set model config -------# + policy_kwargs['feature_extraction'] = feat_ext + agent_config['policy_kwargs'] = policy_kwargs + # config.agent_config = agent_config + # config.model_config = model_config + # if bool(var_agent_configs): #variable configs + # config.var_configs["agent"] = var_agent_configs + # if bool(var_model_configs): + # config.var_configs["model"] = var_model_configs + return agent_config, model_config, var_agent_configs, var_model_configs + + +# change model_config to baselines framework/ decide MLP or CNN policy +def model_to_policy_kwargs(feat_ext, model_config): + # -------------- Model configuration ------------# + # # decide whether to use cnn or mlp, taken from ray code.. + # # Discrete/1D obs-spaces. + # if isinstance(env.observation_space, gym.spaces.Discrete) or \ + # len(env.observation_space.shape) <= 2: + # feat_ext = "mlp" + # else: # Default Conv2D net. + # feat_ext = "cnn" + + # Move model config(already on baselines framework) to policy_kwargs + policy_kwargs, cnn_config = {}, {} + for key in model_config["model"].keys(): + if(key == "act_fun"): + policy_kwargs[key] = act_fnc_from_name(model_config["model"][key]) + else: + policy_kwargs[key] = model_config["model"][key] + + if("use_lstm" in policy_kwargs.keys()): + # use_lstm does not exist in baselines, here is used to define the policy + use_lstm = policy_kwargs.pop("use_lstm") + else: + use_lstm = False + + if("n_lstm" in policy_kwargs.keys() and not use_lstm): + policy_kwargs.pop("n_lstm") # not valid if not lstm policy + + # Custom Feature extractor + if(feat_ext == "cnn" and ("net_arch" in policy_kwargs)): + cnn_config["act_fun"] = act_fnc_from_name(policy_kwargs.pop("act_fun")) + cnn_config["net_arch"] = policy_kwargs.pop("net_arch") + # Uncomment to pass through custom cnn + policy_kwargs['cnn_extractor'] = vision_net + policy_kwargs["kwargs"] = cnn_config + + policy_kwargs['feature_extraction'] = feat_ext + # # add policy arguments to agent configuration + # if('lr_schedule'in agent_config.keys()): #schedule is part of model instead of agent in baselines + # agent_config['policy_kwargs']['lr_schedule'] = agent_config['lr_schedule'] + + return policy_kwargs, use_lstm + + +def act_fnc_from_name(key): + if(key == "tanh"): + return tf.nn.tanh + elif(key == "sigmoid"): + return tf.nn.sigmoid + elif(key == "leakyrelu"): + return tf.nn.leaky_relu + else: #default + return tf.nn.relu + + +def vision_net(scaled_images, kwargs): + if ("act_fun" in kwargs): + activ_fn = kwargs['act_fun'] + else: #default + activ_fn = tf.nn.relu + + output, i = scaled_images, 0 + for i, layer_def in enumerate(kwargs['net_arch'][:-1], start=1): + n_filters, kernel, stride = layer_def + scope = "c%d"%(i) + output = activ_fn(conv(output, scope, n_filters = n_filters, filter_size = kernel[0], stride = stride, pad="SAME", init_scale=np.sqrt(2))) + + #last layer has valid padding + n_filters, kernel, stride = kwargs['net_arch'][-1] + output = activ_fn(conv(output, scope = "c%d"%(i+1), n_filters = n_filters, filter_size = kernel[0], stride = stride, pad="VALID", init_scale=np.sqrt(2))) + output = conv_to_fc(output) #No linear layer + #output = activ_fn(linear(output, 'fc1', n_hidden=512, init_scale=np.sqrt(2))) + return output + + +def init_agent(env, config_algorithm, agent_config_baselines, use_lstm): + #Use feed forward policies and specify cnn feature extractor in configuration + if config_algorithm == 'DQN': + model = DQN(env = env, policy = sb.deepq.policies.FeedForwardPolicy, **agent_config_baselines, verbose=1) + elif config_algorithm == 'DDPG': + # action noise is none by default meaning it does not explore.. + # condiguration using ray defaults + # https://docs.ray.io/en/latest/rllib-algorithms.html?highlight=ddpg#deep-deterministic-policy-gradients-ddpg-td3 + n_actions = env.action_space.shape[0] + agent_config_baselines["action_noise"] = OrnsteinUhlenbeckActionNoise( + mean=np.zeros(n_actions),\ + sigma=float(0.2) * np.ones(n_actions)) + #ddpg + #can also use as agent parameter "normalize_observations = True " or "normalize_returns" = True + model = DDPG(env = env, policy = sb.ddpg.policies.FeedForwardPolicy, **agent_config_baselines, verbose=1 ) + elif config_algorithm == "TD3": + model = TD3(env = env, policy = sb.td3.policies.FeedForwardPolicy, **agent_config_baselines, verbose=1 ) + elif config_algorithm == "A3C" or config_algorithm == "A2C": + policy = sb.common.policies.LstmPolicy if use_lstm else sb.common.policies.FeedForwardPolicy + model = A2C(env = env, policy = policy ,**agent_config_baselines, verbose=1) + else: #'SAC + model = SAC(env = env, policy = sb.sac.policies.FeedForwardPolicy ,**agent_config_baselines, verbose=1) + + +class CustomCallback(sb.common.callbacks.BaseCallback): + """ + Callback for evaluating an agent. + :param eval_env: (Union[gym.Env, VecEnv]) The environment used for initialization + :param n_eval_episodes: (int) The number of episodes to test the agent + :param eval_freq: (int) Evaluate the agent every eval_freq call of the callback. + :param deterministic: (bool) Whether the evaluation should use a stochastic or deterministic actions. + :param verbose: (int) + """ + + def __init__( + self, + eval_env: Union[gym.Env, VecEnv], + n_eval_episodes: int = 5, + eval_interval: int = 1, + timesteps_per_iteration: int = 1000, + deterministic: bool = True, + verbose: int = 1, + file_name: str = "./evaluation.csv", + config_algorithm: str ="", + var_configs = None + ): + super(CustomCallback, self).__init__(verbose=verbose) + self.n_eval_episodes = n_eval_episodes + self.eval_freq = timesteps_per_iteration * eval_interval + self.deterministic = deterministic + self.file_name = file_name + self.timesteps_per_iteration = timesteps_per_iteration + self.training_iteration = 1 + self.total_timesteps = 0 + self.config_algorithm = config_algorithm + self.var_configs = var_configs + self.last_episode_count = 0 + self.episodes_in_iter = 0 + self.best_eval_mean = 0 + # self.best_train_return = 0 + # Convert to VecEnv for consistency + if not isinstance(eval_env, VecEnv): + eval_env = DummyVecEnv([lambda: eval_env]) + eval_env = VecNormalize(eval_env, norm_obs=False, norm_reward=True, clip_obs=10.) + + if isinstance(eval_env, VecEnv): + assert eval_env.num_envs == 1, "You must pass only one environment for evaluation" + + self.eval_env = eval_env + + # evaluate policy when step % eval_freq == 0, return rewards and lengths list of n_eval_episodes elements + def _on_step(self): + # count steps + self.total_timesteps+=1 + # training log + # training iteration done, log train csv + if(self.total_timesteps % self.timesteps_per_iteration == 0): + self.write_train_result() + self.training_iteration += 1 + + # evaluation + if self.eval_freq > 0 and self.n_calls % self.eval_freq == 0: + # Sync training and eval env if there is VecNormalize + sync_envs_normalization(self.training_env, self.eval_env) + + episode_rewards, episode_lengths = sb.common.evaluation.evaluate_policy( + self.model, + self.eval_env, + n_eval_episodes=self.n_eval_episodes, + render=False, + deterministic=self.deterministic, + return_episode_rewards=True, + ) + + # write evaluation csv + self.write_eval_results(episode_rewards, episode_lengths) + + mean_reward, std_reward = np.mean(episode_rewards), np.std(episode_rewards) + mean_ep_length, std_ep_length = np.mean(episode_lengths), np.std(episode_lengths) + + if(self.best_eval_mean < mean_reward): + self.model.save("%s_best_eval" % (self.file_name)) + self.best_eval_mean = mean_reward + + if self.verbose > 0: + print(f"Eval num_timesteps={self.num_timesteps}, " f"episode_reward={mean_reward:.2f} +/- {std_reward:.2f}") + print(f"Episode length: {mean_ep_length:.2f} +/- {std_ep_length:.2f}") + return True + + # def _on_rollout_end(self): + # env = self.training_env + # if isinstance(self.training_env, VecEnv): + # env = env.unwrapped.envs[0] # only using one environment + # episode_rewards = env.get_episode_rewards() + # if(episode_rewards[-1] > self.best_train_return): + # self.model.save("%s_best_train" % (self.file_name)) + # self.best_train_return = episode_rewards[-1] + + # Used in callback after every episode has ended during evaluation + # replaces: def on_episode_end(info) + def write_eval_results(self, episode_rewards, episode_lengths): + eval_filename = self.file_name + '_eval.csv' + fout = open(eval_filename, 'a') # hardcoded + for reward_this_episode, length_this_episode in zip(episode_rewards, episode_lengths): + fout.write(str(reward_this_episode[0]) + ' ' + str(length_this_episode) + "\n") + fout.close() + + # Write training stats to CSV file at end of every training iteration + def write_train_result(self): + env, training_iteration, total_timesteps = self.training_env, self.training_iteration, self.total_timesteps + config_algorithm, var_configs = self.config_algorithm, self.var_configs + + if isinstance(env, VecEnv): + env = env.unwrapped.envs[0] # only using one environment + + #A2C can handle multiple envs.. + # if(self.config_algorithm == "A2C" or self.config_algorithm =="A3C"): + # env = env.envs[0]#take first env + + # Writes every iteration, would slow things down. #hack + fout = open(self.file_name + '.csv', 'a') #hardcoded + fout.write(str(training_iteration) + ' ' + config_algorithm + ' ') + for config_type, config_dict in var_configs.items(): + for key in config_dict: + if config_type == "env": + env_config = env.config + if key == 'reward_noise': + fout.write(str(env_config['reward_noise_std']) + ' ') #hack + elif key == 'transition_noise' and env_config["state_space_type"] == "continuous": + fout.write(str(env_config['transition_noise_std']) + ' ') #hack + else: + fout.write(str(env_config[key]).replace(' ', '') + ' ') + elif config_type == "agent": + fout.write(str(getattr(self.model, key)).replace(' ', '') + ' ') + elif config_type == "model": + if(key == "net_arch"):#this is kwargs as it is sent to visionet + fout.write(str(getattr(self.model, "policy_kwargs")["kwargs"][key]).replace(' ', '') + ' ') + else: + fout.write(str(getattr(self.model, "policy_kwargs")[key]).replace(' ', '') + ' ') + + # Write train statss + episode_rewards = env.get_episode_rewards() + episode_lengths = env.get_episode_lengths() + # update episodes + n_episodes = len(episode_rewards) + self.episodes_in_iter = n_episodes - self.last_episode_count + if(self.episodes_in_iter == 0): # no episodes in iteration + if(n_episodes) == 0: # special case when there are no episodes so far + episode_reward_mean = np.sum(env.rewards) # cummulative reward so far + episode_len_mean = env.get_total_steps() # all steps so far + else: + # iteration end, no episode end + # start = self.timesteps_per_iteration*training_iteration + # episode_reward_mean = np.sum(env.rewards[start:]) + # episode_length_mean = self.timesteps_per_iteration + episode_reward_mean = np.mean(episode_rewards) + episode_length_mean = self.timesteps_per_iteration + else: + # episode stats are from all steps taken in env then we need to take mean over "iterations": + # start , stop = self.last_episode_count, self.last_episode_count + self.episodes_in_iter - 1 + episode_reward_mean = np.mean(episode_rewards[self.last_episode_count:]) + episode_length_mean = np.mean(episode_lengths[self.last_episode_count:]) + self.last_episode_count = n_episodes + + # timesteps_total always HAS to be the 1st written: analysis.py depends on it + fout.write(str(total_timesteps) + ' ' + + str(episode_reward_mean) + + ' ' + str(episode_length_mean) + '\n') + fout.close() + + # We did not manage to find an easy way to log evaluation stats for Ray without the following hack which demarcates the end of a training iteration in the evaluation stats file + hack_filename_eval = self.file_name + '_eval.csv' + fout = open(hack_filename_eval, 'a') #hardcoded + fout.write('#HACK STRING EVAL' + "\n") + fout.close() + + #info["result"]["callback_ok"] = True + return True \ No newline at end of file diff --git a/mdp_playground/config_processor/config_processor.py b/mdp_playground/config_processor/config_processor_old.py similarity index 100% rename from mdp_playground/config_processor/config_processor.py rename to mdp_playground/config_processor/config_processor_old.py diff --git a/run_experiments.py b/run_experiments.py index 473888a..3501929 100644 --- a/run_experiments.py +++ b/run_experiments.py @@ -23,7 +23,7 @@ def parse_args(): def main(): args = parse_args() if args.framework is not None: # get from arguments - framework = args.framework + framework = args.framework else: #check config file if args.config_file[-3:] == '.py': args.config_file = args.config_file[:-3] diff --git a/run_experiments_baselines.py b/run_experiments_baselines.py index ab0a78d..5842f11 100644 --- a/run_experiments_baselines.py +++ b/run_experiments_baselines.py @@ -23,218 +23,13 @@ from gym.wrappers.time_limit import TimeLimit #from gym.wrappers.monitor import Monitor -import tensorflow as tf import stable_baselines as sb from stable_baselines import DQN, DDPG, SAC, A2C, TD3 -from stable_baselines.common.noise import NormalActionNoise, OrnsteinUhlenbeckActionNoise -from stable_baselines.common.vec_env import DummyVecEnv, VecNormalize, VecEnv -from stable_baselines.common.env_checker import check_env -from stable_baselines.common.tf_layers import conv, linear, conv_to_fc, lstm -from stable_baselines.common.vec_env import DummyVecEnv, VecEnv, sync_envs_normalization -from typing import Any, Dict, List, Optional, Union - -from functools import reduce +from stable_baselines.common.noise import OrnsteinUhlenbeckActionNoise +from stable_baselines.common.vec_env import DummyVecEnv, VecNormalize import time -import itertools import pprint - - -def create_gym_env_wrapper_atari(config): - from gym.envs.atari import AtariEnv - from mdp_playground.envs.gym_env_wrapper import GymEnvWrapper - ae = AtariEnv(**config["AtariEnv"]) - gew = GymEnvWrapper(ae, **config) ##IMP Had initially thought to put this config in config["GymEnvWrapper"] but because of code below which converts var_env_configs to env_config, it's best to leave those configs as top level configs in the dict! - return gew - -def create_gym_env_wrapper_frame_stack_atari(config): #hack ###TODO remove? - '''When using frameStack GymEnvWrapper should wrap AtariEnv using wrap_deepmind_ray and therefore this function sets "wrap_deepmind_ray": True and 'frame_skip': 1 inside config so as to keep config same as for create_gym_env_wrapper_atari above and reduce manual errors when switching between the 2. - ''' - config["wrap_deepmind_ray"] = True #hack - config["frame_skip"] = 1 #hack - from gym.envs.atari import AtariEnv - from mdp_playground.envs.gym_env_wrapper import GymEnvWrapper - import gym - game = config["AtariEnv"]["game"] - game = ''.join([g.capitalize() for g in game.split('_')]) - ae = gym.make('{}NoFrameskip-v4'.format(game)) - gew = GymEnvWrapper(ae, **config) ##IMP Had initially thought to put this config in config["GymEnvWrapper"] but because of code below which converts var_env_configs to env_config, it's best to leave those configs as top level configs in the dict! - return gew - - -class CustomCallback(sb.common.callbacks.BaseCallback): - """ - Callback for evaluating an agent. - :param eval_env: (Union[gym.Env, VecEnv]) The environment used for initialization - :param n_eval_episodes: (int) The number of episodes to test the agent - :param eval_freq: (int) Evaluate the agent every eval_freq call of the callback. - :param deterministic: (bool) Whether the evaluation should use a stochastic or deterministic actions. - :param verbose: (int) - """ - - def __init__( - self, - eval_env: Union[gym.Env, VecEnv], - n_eval_episodes: int = 5, - eval_interval: int = 1, - timesteps_per_iteration: int = 1000, - deterministic: bool = True, - verbose: int = 1, - file_name: str = "./evaluation.csv", - config_algorithm: str ="", - var_configs = None - ): - super(CustomCallback, self).__init__(verbose=verbose) - self.n_eval_episodes = n_eval_episodes - self.eval_freq = timesteps_per_iteration * eval_interval - self.deterministic = deterministic - self.file_name = file_name - self.timesteps_per_iteration = timesteps_per_iteration - self.training_iteration = 1 - self.total_timesteps = 0 - self.config_algorithm = config_algorithm - self.var_configs = var_configs - self.last_episode_count = 0 - self.episodes_in_iter = 0 - self.best_eval_mean = 0 - # self.best_train_return = 0 - # Convert to VecEnv for consistency - if not isinstance(eval_env, VecEnv): - eval_env = DummyVecEnv([lambda: eval_env]) - eval_env = VecNormalize(eval_env, norm_obs=False, norm_reward=True, clip_obs=10.) - - if isinstance(eval_env, VecEnv): - assert eval_env.num_envs == 1, "You must pass only one environment for evaluation" - - self.eval_env = eval_env - - # evaluate policy when step % eval_freq == 0, return rewards and lengths list of n_eval_episodes elements - def _on_step(self): - # count steps - self.total_timesteps+=1 - # training log - # training iteration done, log train csv - if(self.total_timesteps % self.timesteps_per_iteration == 0): - self.write_train_result() - self.training_iteration += 1 - - # evaluation - if self.eval_freq > 0 and self.n_calls % self.eval_freq == 0: - # Sync training and eval env if there is VecNormalize - sync_envs_normalization(self.training_env, self.eval_env) - - episode_rewards, episode_lengths = sb.common.evaluation.evaluate_policy( - self.model, - self.eval_env, - n_eval_episodes=self.n_eval_episodes, - render=False, - deterministic=self.deterministic, - return_episode_rewards=True, - ) - - # write evaluation csv - self.write_eval_results(episode_rewards, episode_lengths) - - mean_reward, std_reward = np.mean(episode_rewards), np.std(episode_rewards) - mean_ep_length, std_ep_length = np.mean(episode_lengths), np.std(episode_lengths) - - if(self.best_eval_mean < mean_reward): - self.model.save("%s_best_eval" % (self.file_name)) - self.best_eval_mean = mean_reward - - if self.verbose > 0: - print(f"Eval num_timesteps={self.num_timesteps}, " f"episode_reward={mean_reward:.2f} +/- {std_reward:.2f}") - print(f"Episode length: {mean_ep_length:.2f} +/- {std_ep_length:.2f}") - return True - - # def _on_rollout_end(self): - # env = self.training_env - # if isinstance(self.training_env, VecEnv): - # env = env.unwrapped.envs[0] # only using one environment - # episode_rewards = env.get_episode_rewards() - # if(episode_rewards[-1] > self.best_train_return): - # self.model.save("%s_best_train" % (self.file_name)) - # self.best_train_return = episode_rewards[-1] - - # Used in callback after every episode has ended during evaluation - # replaces: def on_episode_end(info) - def write_eval_results(self, episode_rewards, episode_lengths): - eval_filename = self.file_name + '_eval.csv' - fout = open(eval_filename, 'a') # hardcoded - for reward_this_episode, length_this_episode in zip(episode_rewards, episode_lengths): - fout.write(str(reward_this_episode[0]) + ' ' + str(length_this_episode) + "\n") - fout.close() - - # Write training stats to CSV file at end of every training iteration - def write_train_result(self): - env, training_iteration, total_timesteps = self.training_env, self.training_iteration, self.total_timesteps - config_algorithm, var_configs = self.config_algorithm, self.var_configs - - if isinstance(env, VecEnv): - env = env.unwrapped.envs[0] # only using one environment - - #A2C can handle multiple envs.. - # if(self.config_algorithm == "A2C" or self.config_algorithm =="A3C"): - # env = env.envs[0]#take first env - - # Writes every iteration, would slow things down. #hack - fout = open(self.file_name + '.csv', 'a') #hardcoded - fout.write(str(training_iteration) + ' ' + config_algorithm + ' ') - for config_type, config_dict in var_configs.items(): - for key in config_dict: - if config_type == "env": - env_config = env.config - if key == 'reward_noise': - fout.write(str(env_config['reward_noise_std']) + ' ') #hack - elif key == 'transition_noise' and env_config["state_space_type"] == "continuous": - fout.write(str(env_config['transition_noise_std']) + ' ') #hack - else: - fout.write(str(env_config[key]).replace(' ', '') + ' ') - elif config_type == "agent": - fout.write(str(getattr(self.model, key)).replace(' ', '') + ' ') - elif config_type == "model": - if(key == "net_arch"):#this is kwargs as it is sent to visionet - fout.write(str(getattr(self.model, "policy_kwargs")["kwargs"][key]).replace(' ', '') + ' ') - else: - fout.write(str(getattr(self.model, "policy_kwargs")[key]).replace(' ', '') + ' ') - - # Write train statss - episode_rewards = env.get_episode_rewards() - episode_lengths = env.get_episode_lengths() - # update episodes - n_episodes = len(episode_rewards) - self.episodes_in_iter = n_episodes - self.last_episode_count - if(self.episodes_in_iter == 0): # no episodes in iteration - if(n_episodes) == 0: # special case when there are no episodes so far - episode_reward_mean = np.sum(env.rewards) # cummulative reward so far - episode_len_mean = env.get_total_steps() # all steps so far - else: - # iteration end, no episode end - # start = self.timesteps_per_iteration*training_iteration - # episode_reward_mean = np.sum(env.rewards[start:]) - # episode_length_mean = self.timesteps_per_iteration - episode_reward_mean = np.mean(episode_rewards) - episode_length_mean = self.timesteps_per_iteration - else: - # episode stats are from all steps taken in env then we need to take mean over "iterations": - # start , stop = self.last_episode_count, self.last_episode_count + self.episodes_in_iter - 1 - episode_reward_mean = np.mean(episode_rewards[self.last_episode_count:]) - episode_length_mean = np.mean(episode_lengths[self.last_episode_count:]) - self.last_episode_count = n_episodes - - # timesteps_total always HAS to be the 1st written: analysis.py depends on it - fout.write(str(total_timesteps) + ' ' + - str(episode_reward_mean) + - ' ' + str(episode_length_mean) + '\n') - fout.close() - - # We did not manage to find an easy way to log evaluation stats for Ray without the following hack which demarcates the end of a training iteration in the evaluation stats file - hack_filename_eval = self.file_name + '_eval.csv' - fout = open(hack_filename_eval, 'a') #hardcoded - fout.write('#HACK STRING EVAL' + "\n") - fout.close() - - #info["result"]["callback_ok"] = True - return True +from mdp_playground.config_processor.baselines_processor import * def parse_args(): @@ -252,85 +47,6 @@ def parse_args(): print("Parsed args:", args) return args -def deepmerge(a, b, path=None): - '''Merges dict b into dict a - - Based on: https://stackoverflow.com/questions/7204805/how-to-merge-dictionaries-of-dictionaries/7205107#7205107 - ''' - if path is None: path = [] - for key in b: - if key in a: - if isinstance(a[key], dict) and isinstance(b[key], dict): - deepmerge(a[key], b[key], path + [str(key)]) - elif a[key] == b[key]: - pass # same leaf value - else: - raise Exception('Conflict at %s' % '.'.join(path + [str(key)])) - else: - a[key] = b[key] - return a - -def cartesian_prod(args, config): - value_tuples = [] - for config_type, config_dict in config.var_configs.items(): - for key in config_dict: - assert type(config.var_configs[config_type][key]) == list, "var_config should be a dict of dicts with lists as the leaf values to allow each configuration option to take multiple possible values" - value_tuples.append(config.var_configs[config_type][key]) - - cartesian_product_configs = list(itertools.product(*value_tuples)) - print("Total number of configs. to run:", len(cartesian_product_configs)) - - if args.config_num is None: - pass - else: - cartesian_product_configs = [cartesian_product_configs[args.config_num]] - - return cartesian_product_configs - -def default_timesteps_total(env_config, algorithm): - #default settings for #timesteps_total - if env_config["env"] in ["HalfCheetahWrapper-v3"]: #hack - timesteps_total = 3000000 - - # from mdp_playground.envs.mujoco_env_wrapper import get_mujoco_wrapper #hack - # from gym.envs.mujoco.half_cheetah_v3 import HalfCheetahEnv - # wrapped_mujoco_env = get_mujoco_wrapper(HalfCheetahEnv) - # register_env("HalfCheetahWrapper-v3", lambda config: create_gym_env_wrapper_mujoco_wrapper(config, wrapped_mujoco_env)) - - elif env_config["env"] in ["HopperWrapper-v3"]: #hack - timesteps_total = 1000000 - # from mdp_playground.envs.mujoco_env_wrapper import get_mujoco_wrapper #hack - # from gym.envs.mujoco.hopper_v3 import HopperEnv - # wrapped_mujoco_env = get_mujoco_wrapper(HopperEnv) - # register_env("HopperWrapper-v3", lambda config: create_gym_env_wrapper_mujoco_wrapper(config, wrapped_mujoco_env)) - - elif env_config["env"] in ["PusherWrapper-v2"]: #hack - timesteps_total = 500000 - - # from mdp_playground.envs.mujoco_env_wrapper import get_mujoco_wrapper #hack - # from gym.envs.mujoco.pusher import PusherEnv - # wrapped_mujoco_env = get_mujoco_wrapper(PusherEnv) - # register_env("PusherWrapper-v2", lambda config: create_gym_env_wrapper_mujoco_wrapper(config, wrapped_mujoco_env)) - - elif env_config["env"] in ["ReacherWrapper-v2"]: #hack - timesteps_total = 500000 - - # from mdp_playground.envs.mujoco_env_wrapper import get_mujoco_wrapper #hack - # from gym.envs.mujoco.reacher import ReacherEnv - # wrapped_mujoco_env = get_mujoco_wrapper(ReacherEnv) - # register_env("ReacherWrapper-v2", lambda config: create_gym_env_wrapper_mujoco_wrapper(config, wrapped_mujoco_env)) - - elif env_config["env"] in ["GymEnvWrapper-Atari"]: - if "AtariEnv" in env_config["env_config"]: - timesteps_total = 10_000_000 - else: - if algorithm == 'DQN': - timesteps_total = 20000 - elif algorithm == 'A3C' or algorithm == "A2C": - timesteps_total = 150000 - else: #if algorithm == 'DDPG': - timesteps_total = 20000 - return timesteps_total def process_dictionaries(config, current_config, var_env_configs, var_agent_configs, var_model_configs): algorithm = config.algorithm @@ -392,285 +108,6 @@ def process_dictionaries(config, current_config, var_env_configs, var_agent_conf return agent_config, model_config, env_config -def vision_net(scaled_images, kwargs): - if ("act_fun" in kwargs): - activ_fn = kwargs['act_fun'] - else: #default - activ_fn = tf.nn.relu - - output, i = scaled_images, 0 - for i, layer_def in enumerate(kwargs['net_arch'][:-1], start=1): - n_filters, kernel, stride = layer_def - scope = "c%d"%(i) - output = activ_fn(conv(output, scope, n_filters = n_filters, filter_size = kernel[0], stride = stride, pad="SAME", init_scale=np.sqrt(2))) - - #last layer has valid padding - n_filters, kernel, stride = kwargs['net_arch'][-1] - output = activ_fn(conv(output, scope = "c%d"%(i+1), n_filters = n_filters, filter_size = kernel[0], stride = stride, pad="VALID", init_scale=np.sqrt(2))) - output = conv_to_fc(output) #No linear layer - #output = activ_fn(linear(output, 'fc1', n_hidden=512, init_scale=np.sqrt(2))) - return output - -def act_fnc_from_name(key): - if(key == "tanh"): - return tf.nn.tanh - elif(key == "sigmoid"): - return tf.nn.sigmoid - elif(key == "leakyrelu"): - return tf.nn.leaky_relu - else: #default - return tf.nn.relu - -#change config.agent_config, config.var_model_config and config.var_agent_config to baselines framework -def agent_to_baselines(config): - policy_kwargs = {} - algorithm, agent_config, model_config = config.algorithm, config.agent_config, config.model_config - try: - var_agent_configs = config.var_agent_configs - except AttributeError: - var_agent_configs = {} #var_model_configs does not exist - try: - var_model_configs = config.var_model_configs - except AttributeError: - var_model_configs = {} #var_model_configs does not exist - - valid_keys = ["gamma", "buffer_size", "batch_size", "learning_starts","timesteps_per_iteration"]#common - agent_to_model = []#none - #Check correct keys for each algorithm - if algorithm == 'DQN': - #change keys in dictionaries to something baselines understands - valid_keys += ["exploration_fraction","exploration_final_eps", "exploration_initial_eps", - "train_freq", "double_q", - "prioritized_replay", "prioritized_replay_alpha", - "param_noise", "learning_rate", "target_network_update_freq"] - - exchange_keys = [('noisy', 'param_noise'), - ('lr','learning_rate'), - ('train_batch_size', 'batch_size'), - ("rollout_fragment_length", "train_freq")] - #Move dueling to policy parameters - agent_to_model+=[("dueling","dueling")] - elif algorithm == "DDPG": - #memory_policy can be used to select PER - #random_exploration, param_noise, action_noise parameters aditional - valid_keys += ["critic_lr", "actor_lr", "tau","critic_l2_reg",\ - "clip_norm", "nb_rollout_steps", "nb_train_steps"] - valid_keys.remove("learning_starts") #For some reason it's the only one that does not have this implemented - exchange_keys = [ - ('rollout_fragment_length','nb_rollout_steps'), - ("l2_reg", "critic_l2_reg"), - ("grad_norm_clipping", "clip_norm"), - ('train_batch_size', 'batch_size')] - # Because of how DDPG is implemented it will perform 100 rollout steps and then 50 train steps - # This needs to be changed s.t. it does one rollout step and one training step - agent_config["nb_rollout_steps"] = 1 - agent_config["nb_train_steps"] = 1 - agent_to_model+=[("actor_hiddens", "layers"),("critic_hiddens", "layers")]#cannot specify different nets - #SPECIAL CASE, learning rates SHOULD NOT be none :c - for key in ["critic_lr", "actor_lr"]: - key_not_none = agent_config.get(key) - if (key in agent_config): - if(not key_not_none): #key==none - agent_config.pop(key) #remove to get default value - - elif algorithm == "TD3": - #memory_policy can be used to select PER; policy is always smoothened - #random_exploration, param_noise, action_noise parameters aditional - valid_keys += ["learning_rate", "policy_delay","tau","train_freq","gradient_steps",\ - "target_policy_noise","target_noise_clip","action_noise"] - exchange_keys = [ - ("target_noise", "target_policy_noise"), - ("critic_lr", "learning_rate"), - ("actor_lr", "learning_rate"), - ('train_batch_size', 'batch_size')] - agent_to_model+=[("actor_hiddens", "layers"),("critic_hiddens", "layers")] - #SPECIAL CASE, learning rates SHOULD NOT be none :c - for key in ["critic_lr, actor_lr"]: - key_not_none = agent_config.get(key) - if (key in agent_config): - if(not key_not_none): - agent_config.pop(key) #remove to get default value - # Because of how TD3 is implemented it will perform 100 grad steps every 100 steps - # This needs to be changed s.t. it does one rollout step and one training step - agent_config["train_freq"] = 1 - agent_config["gradient_steps"] = 1 - agent_config["action_noise"] = NormalActionNoise(mean=0, sigma=0) #s.t. it clips actions between [-1,1] - elif algorithm == "SAC": - valid_keys += ["learning_rate", "tau", "ent_coef","train_freq", - "target_update_interval","clip_norm","target_entropy"] - exchange_keys = [ - ("rollout_fragment_length","train_freq"), - ("entropy_learning_rate","learning_rate"), #same learning rate for - ("critic_learning_rate", "learning_rate"), #entropy - ("actor_learning_rate", "learning_rate"), #actor and critic - ("target_network_update_freq","target_update_interval"), - ("grad_norm_clipping", "clip_norm"), - ('train_batch_size', 'batch_size')] - agent_to_model+=[("fcnet_hiddens", "layers")] - #-------- Add init entropy coef ------------# - if("initial_alpha" in agent_config.keys()): - agent_config["ent_coef"] = "auto_%.3f"%agent_config["initial_alpha"] #idk why but that's how baselines initializes this thing.. - agent_config.pop("initial_alpha") - #var agent configs initial_alpha - #idk why but that's how baselines initializes this thing.. - if("agent" in config.var_configs): - if("initial_alpha" in var_agent_configs): - var_agent_configs["ent_coef"] = ["auto_%.3f"%coef for coef in var_agent_configs["initial_alpha"]] - var_agent_configs.pop("initial_alpha") - # ----------- special case ---------# - #should be at least one - if("target_network_update_freq" in config.agent_config): - key_val = agent_config["target_network_update_freq"] - agent_config["target_network_update_freq"] = 1 if key_val <= 0 else key_val - #-------- Take things out of optimization ------------# - #Special case: Optimization - if("optimization" in agent_config): - for k in config.agent_config["optimization"].keys(): - key_value = config.agent_config["optimization"][k] - if(key_value): #not none - agent_config[k] = key_value - #-------- Take things out of Q-model and policy_model ------------# - #Can only specify one model for everything - for move_key in ["Q_model", "policy_model"]: - if(move_key in model_config): - if("model" not in model_config):#init - model_config["model"]={} - for k in config.model_config[move_key].keys(): - model_config["model"][k] = config.model_config[move_key][k] - model_config.pop(move_key)#Remove from model_config - else: #A2C - config.algorithm = "A2C" - valid_keys += ["learning_rate","vf_coef", "ent_coef","max_grad_norm"] #"lr_schedule" cannot be none - exchange_keys = [ - ("vf_loss_coeff","vf_coef"), - ("entropy_coeff","ent_coef"), - ("lr", "learning_rate"), - ("grad_clip", "max_grad_norm")] - - #-------- Change keys from Agent to Model dict when needed--------# - for key_tuple in agent_to_model: - old_key, new_key = key_tuple - #-------- Agent config --------# - key_exists = agent_config.get(old_key) - if key_exists:#If key exists and is not none - policy_kwargs[new_key] = agent_config.pop(old_key) #Move key to model config - # #-------- Var agent config --------# - key_exists = var_agent_configs.get(old_key) - if key_exists:#If key exists and is not none - var_model_configs[new_key] = var_agent_configs.pop(old_key) #Move key to model config - - if('fcnet_hiddens' in agent_config.keys()): - policy_kwargs['layers'] = agent_config['fcnet_hiddens'] - agent_config.pop('fcnet_hiddens') - - #-------- Agent config --------# - #change agent keys - for key_tuple in exchange_keys: - old_key, new_key = key_tuple - #-------- Agent config --------# - if(old_key in agent_config): - agent_config[new_key] = agent_config.pop(old_key) - #-------- Var agent config --------# - if(old_key in var_agent_configs): - var_agent_configs[new_key] = var_agent_configs.pop(old_key) - - #remove keys from dictionary which are not configurable by baselines - for key in list(agent_config.keys()): - if( key not in valid_keys ):#delete invalid keys - agent_config.pop(key) - - #-------- Var agent config --------# - #remove keys from dictionary which are not configurable by baselines - for key in list(var_agent_configs.keys()): - if( key not in valid_keys ):#delete invalid keys - var_agent_configs.pop(key) - - #----------- Model config ----------------# - valid_keys = ["act_fun", "net_arch", "feature_extractor", "layers", "use_lstm","n_lstm"] - exchange_keys = [("fcnet_activation", "act_fun"), - ("conv_activation", "act_fun"), - ("actor_hidden_activation", "act_fun"), - ("actor_hidden_activation", "act_fun"), - ("fcnet_hiddens", "layers"), - ("actor_hiddens", "layers"), - ("critic_hiddens","layers"), - ("conv_filters", "net_arch"), - ("lstm_cell_size","n_lstm")] - - #change keys - for key_tuple in exchange_keys: - old_key, new_key = key_tuple - #-------- model config --------# - if(old_key in model_config["model"]): - model_config["model"][new_key] = model_config["model"].pop(old_key) - - #-------- Var model config --------# - if(old_key in var_model_configs): - var_model_configs[new_key] = var_model_configs.pop(old_key) - - #remove invalid keys - for key in list(model_config["model"].keys()): - if( key not in valid_keys ): - model_config["model"].pop(key) - - #-------- Var model config - delete invalid keys -------# - for key in list(var_model_configs.keys()): - if( key not in valid_keys ): - var_model_configs.pop(key) - - #-------- set model config -------# - agent_config['policy_kwargs'] = policy_kwargs - config.agent_config = agent_config - config.model_config = model_config - if bool(var_agent_configs): #variable configs - config.var_configs["agent"] = var_agent_configs - if bool(var_model_configs): - config.var_configs["model"] = var_model_configs - return config, var_agent_configs, var_model_configs - -#change config.model_config to baselines framework/ decide MLP or CNN policy -def model_to_policy_kwargs(env, config): - model_config = config.model_config - #-------------- Model configuration ------------# - #decide whether to use cnn or mlp, taken from ray code.. - # Discrete/1D obs-spaces. - if isinstance(env.observation_space, gym.spaces.Discrete) or \ - len(env.observation_space.shape) <= 2: - feat_ext ="mlp" - else:# Default Conv2D net. - feat_ext = "cnn" - - #Move model config(already on baselines framework) to policy_kwargs - policy_kwargs, cnn_config = {}, {} - for key in model_config["model"].keys(): - if( key == "act_fun" ): - policy_kwargs[key] = act_fnc_from_name( model_config["model"][key] ) - else: - policy_kwargs[key] = model_config["model"][key] - - if("use_lstm" in policy_kwargs.keys()): - #use_lstm does not exist in baselines, here is used to define the policy - use_lstm = policy_kwargs.pop("use_lstm") - else: - use_lstm = False - - if("n_lstm" in policy_kwargs.keys() and not use_lstm): - policy_kwargs.pop("n_lstm")#not valid if not lstm policy - - #Custom Feature extractor - if(feat_ext == "cnn" and ("net_arch" in policy_kwargs)): - cnn_config["act_fun"] = act_fnc_from_name( policy_kwargs.pop("act_fun") ) - cnn_config["net_arch"] = policy_kwargs.pop("net_arch") - #Uncomment to pass through custom cnn - policy_kwargs['cnn_extractor'] = vision_net - policy_kwargs["kwargs"] = cnn_config - - policy_kwargs['feature_extraction'] = feat_ext - # #add policy arguments to agent configuration - # if('lr_schedule'in agent_config.keys()): #schedule is part of model instead of agent in baselines - # agent_config['policy_kwargs']['lr_schedule'] = agent_config['lr_schedule'] - - return policy_kwargs, use_lstm def main(args): # print("Config file", os.path.abspath(args.config_file)) # 'experiments/dqn_seq_del.py' @@ -692,7 +129,7 @@ def main(args): stats_file_name = args.exp_name + '_' + str(args.config_num) print("Stats file being written to:", stats_file_name) - #------------------------- Variable configurations ----------------------------# + # ------------------------- Variable configurations ----------------------------# config, var_agent_configs, var_model_configs = agent_to_baselines(config) var_configs_deepcopy = copy.deepcopy(config.var_configs) #hack because this needs to be read in on_train_result and trying to read config there raises an error because it's been imported from a Python module and I think they try to reload it there. @@ -710,7 +147,7 @@ def main(args): for key in config_dict: configs_to_print += str(config_dict[key]) + ', ' - print(config.algorithm, configs_to_print) + print(config_algorithm, configs_to_print) #----------------- Write headers to csv file --------------------# hack_filename = stats_file_name + '.csv' @@ -721,95 +158,77 @@ def main(args): fout.write(key + ', ') fout.write('timesteps_total, episode_reward_mean, episode_len_mean\n') fout.close() - + #---------- Compute cartesian product of configs ----------------# start = time.time() - # cartesian_product_configs = cartesian_prod(args, config) if args.config_num is None: - cartesian_product_configs = config.cartesian_product_configs + cartesian_product_configs = config.final_configs else: - cartesian_product_configs = [config.cartesian_product_configs[args.config_num]] + cartesian_product_configs = [config.final_configs[args.config_num]] - #------------ Run every configuration ------------------ # + # ------------ Run every configuration ------------------ # pp = pprint.PrettyPrinter(indent=4) for i, current_config in enumerate(cartesian_product_configs): - print("Configuration: %d \t %d remaining"%(i, len(cartesian_product_configs) - i )) - #------------ Dictionaries setup ------------------ # - agent_config, model_config, env_config = process_dictionaries(config, current_config, var_env_configs, var_agent_configs, var_model_configs) #hacks - - #------------ Env init ------------------ # - env = gym.make(env_config['env'],**env_config['env_config']) - - #if time limit, wrap it - if( "horizon" in env_config ): - train_horizon = env_config["horizon"] - env = TimeLimit(env, max_episode_steps = train_horizon) #horizon - env = sb.bench.Monitor(env, None)#, "../", force=True) + print("Configuration: %d \t %d remaining" + % (i, len(cartesian_product_configs) - i)) + # ------------ Dictionaries setup ------------------ # + agent_config, model_config, env_config = \ + process_dictionaries(config, current_config, var_env_configs, var_agent_configs, var_model_configs) # hacks + + # ------------ Env init ------------------ # + env = gym.make(current_config['env'], + **current_config['env_config']) + + # if time limit, wrap it + if("horizon" in current_config['env']): + train_horizon = current_config['env']["horizon"] + env = TimeLimit(env, max_episode_steps=train_horizon) # horizon + env = sb.bench.Monitor(env, None) # , "../", force=True) # Automatically normalize the input features and reward - if (config.algorithm == "DDPG" or config.algorithm == "A2C" or config.algorithm == "A3C"): + if (config_algorithm == "DDPG" + or config_algorithm == "A2C" + or config_algorithm == "A3C"): env = DummyVecEnv([lambda: env]) - env = VecNormalize(env, norm_obs=False, norm_reward=True, clip_obs=10.) - - #limit max timesteps in evaluation + env = VecNormalize(env, + norm_obs=False, + norm_reward=True, + clip_obs=10.) + + # limit max timesteps in evaluation eval_horizon = 100 - eval_env = gym.make(env_config['env'],**env_config['env_config']) - eval_env = TimeLimit(eval_env, max_episode_steps = eval_horizon) #horizon + eval_env = gym.make(env_config['env'], **env_config['env_config']) + eval_env = TimeLimit(eval_env, max_episode_steps=eval_horizon) print("Env config:",) pp.pprint(env_config) #------------ Agent init ------------------ # # Create the agent - if("timesteps_per_iteration" in agent_config): - timesteps_per_iteration = agent_config["timesteps_per_iteration"] - agent_config_baselines = copy.deepcopy(agent_config) - agent_config_baselines.pop('timesteps_per_iteration') #this is not part of baselines parameters, need to separate - else: - timesteps_per_iteration = 1000 # default - - #Set model parameters - policy_kwargs, use_lstm = model_to_policy_kwargs(env, config) #return policy_kwargs - agent_config_baselines["policy_kwargs"] = policy_kwargs - - #Use feed forward policies and specify cnn feature extractor in configuration - if config.algorithm == 'DQN': - model = DQN(env = env, policy = sb.deepq.policies.FeedForwardPolicy, **agent_config_baselines, verbose=1) - elif config.algorithm == 'DDPG': - # action noise is none by default meaning it does not explore.. - # condiguration using ray defaults - # https://docs.ray.io/en/latest/rllib-algorithms.html?highlight=ddpg#deep-deterministic-policy-gradients-ddpg-td3 - n_actions = env.action_space.shape[0] - agent_config_baselines["action_noise"] = OrnsteinUhlenbeckActionNoise( - mean=np.zeros(n_actions),\ - sigma=float(0.2) * np.ones(n_actions)) - #ddpg - #can also use as agent parameter "normalize_observations = True " or "normalize_returns" = True - model = DDPG(env = env, policy = sb.ddpg.policies.FeedForwardPolicy, **agent_config_baselines, verbose=1 ) - elif config.algorithm == "TD3": - model = TD3(env = env, policy = sb.td3.policies.FeedForwardPolicy, **agent_config_baselines, verbose=1 ) - elif config.algorithm == "A3C" or config.algorithm == "A2C": - policy = sb.common.policies.LstmPolicy if use_lstm else sb.common.policies.FeedForwardPolicy - model = A2C(env = env, policy = policy ,**agent_config_baselines, verbose=1) - else: #'SAC - model = SAC(env = env, policy = sb.sac.policies.FeedForwardPolicy ,**agent_config_baselines, verbose=1) + timesteps_per_iteration = current_config["timesteps_per_iteration"] + use_lstm = current_config["use_lstm"] + agent_config_baselines = current_config["agent"] + model = init_agent(env, + config_algorithm, + agent_config_baselines, use_lstm) #------------ train/evaluation ------------------ # - if 'timesteps_total' in dir(config): - timesteps_total = config.timesteps_total - else: - timesteps_total = default_timesteps_total(env_config, config.algorithm) + timesteps_total = config.timesteps_total # train your model for n_iter timesteps #Define evaluation - eval_interval = 1 #every x training iterations - csv_callbacks = CustomCallback(eval_env, n_eval_episodes=10, \ - timesteps_per_iteration = timesteps_per_iteration,\ - eval_interval=eval_interval, deterministic=True, file_name = stats_file_name, \ - config_algorithm = config.algorithm, var_configs = var_configs_deepcopy) + eval_interval = config.evaluation_interval # every x training iterations + csv_callbacks = CustomCallback(eval_env, + n_eval_episodes=10, + timesteps_per_iteration=timesteps_per_iteration, + eval_interval=eval_interval, + deterministic=True, + file_name=stats_file_name, + config_algorithm=config_algorithm, + var_configs=var_configs_deepcopy) #Train learn_params = {"callback": csv_callbacks, "total_timesteps": int(timesteps_total)} - if(config.algorithm == "DDPG"): #Log interval is handled differently for each algorithm, e.g. each log_interval episodes(DQN) or log_interval steps(DDPG). + if(config_algorithm == "DDPG"): #Log interval is handled differently for each algorithm, e.g. each log_interval episodes(DQN) or log_interval steps(DDPG). learn_params["log_interval"] = timesteps_per_iteration else: learn_params["log_interval"] = timesteps_per_iteration//10 From 5e76bdea74104ddf63693300681fa03ce2a265a5 Mon Sep 17 00:00:00 2001 From: JessicaBorja Date: Thu, 13 May 2021 21:58:04 +0200 Subject: [PATCH 10/22] add changes to baselines file and config processor --- experiments/a3c_del.py | 40 ++- .../config_processor/baselines_processor.py | 183 +++++++--- ...g_processor_old.py => config_processor.py} | 315 +++++++++++++++--- run_experiments_baselines.py | 205 +++--------- 4 files changed, 480 insertions(+), 263 deletions(-) rename mdp_playground/config_processor/{config_processor_old.py => config_processor.py} (51%) diff --git a/experiments/a3c_del.py b/experiments/a3c_del.py index 65bd557..9a3d60f 100644 --- a/experiments/a3c_del.py +++ b/experiments/a3c_del.py @@ -1,3 +1,6 @@ +from mdp_playground.config_processor.config_processor import get_grid_of_configs, combined_processing + + num_seeds = 10 timesteps_total = 1000000 from collections import OrderedDict @@ -14,8 +17,18 @@ 'dummy_seed': [i for i in range(num_seeds)], }) +var_agent_configs = OrderedDict({ + # Learning rate + "lr": [1e-3], + # Value Function Loss coefficient + "vf_loss_coeff": [0.1, 0.5, 2.5], + # Entropy coefficient + "entropy_coeff": [0.001, 0.01, 0.1, 1], +}) + var_configs = OrderedDict({ -"env": var_env_configs +"env": var_env_configs, +"agent": var_agent_configs }) env_config = { @@ -45,14 +58,8 @@ "lambda": 0.95, # # Max global norm for each gradient calculated by worker "grad_clip": 10.0, # low prio. - # Learning rate - "lr": 0.0001, # # Learning rate schedule - "lr_schedule": None, - # Value Function Loss coefficient - "vf_loss_coeff": 0.1, # - # Entropy coefficient - "entropy_coeff": 0.1, # + "lr_schedule": "linear", # Min time per iteration "min_iter_time_s": 0, # Workers sample async. Note that this increases the effective @@ -67,9 +74,16 @@ }, } +filters_100x100 = [ + [16, [8, 8], 4], + [32, [4, 4], 2], + [256, [13, 13], 1], +] + model_config = { "model": { "fcnet_hiddens": [128, 128, 128], + "conv_filters": filters_100x100, "custom_preprocessor": "ohe", "custom_options": {}, # extra options to pass to your preprocessor "fcnet_activation": "tanh", @@ -94,13 +108,3 @@ } }, } - -value_tuples = [] -for config_type, config_dict in var_configs.items(): - for key in config_dict: - assert type(var_configs[config_type][key]) == list, "var_config should be a dict of dicts with lists as the leaf values to allow each configuration option to take multiple possible values" - value_tuples.append(var_configs[config_type][key]) - -import itertools -cartesian_product_configs = list(itertools.product(*value_tuples)) -print("Total number of configs. to run:", len(cartesian_product_configs)) diff --git a/mdp_playground/config_processor/baselines_processor.py b/mdp_playground/config_processor/baselines_processor.py index 029e119..89e72b7 100644 --- a/mdp_playground/config_processor/baselines_processor.py +++ b/mdp_playground/config_processor/baselines_processor.py @@ -1,4 +1,5 @@ +from psutil import net_if_addrs from stable_baselines.common.noise import NormalActionNoise, OrnsteinUhlenbeckActionNoise import gym from stable_baselines.common.tf_layers import conv, linear, conv_to_fc, lstm @@ -8,7 +9,8 @@ from typing import Any, Dict, List, Optional, Union from stable_baselines.common.vec_env import DummyVecEnv, VecEnv, sync_envs_normalization from stable_baselines import DQN, DDPG, SAC, A2C, TD3 - +from stable_baselines.common.vec_env import DummyVecEnv, VecNormalize +from gym.wrappers.time_limit import TimeLimit # change config.agent_config, # config.var_model_config @@ -131,15 +133,31 @@ def agent_to_baselines(config): for k in model_config[move_key].keys(): model_config["model"][k] = model_config[move_key][k] model_config.pop(move_key) # Remove from model_config - else: #A2C + else: # A2C algorithm = "A2C" - valid_keys += ["learning_rate","vf_coef", "ent_coef","max_grad_norm"] #"lr_schedule" cannot be none + valid_keys += ["learning_rate", + "vf_coef", + "ent_coef", + "max_grad_norm"] # "lr_schedule" cannot be none exchange_keys = [ ("vf_loss_coeff","vf_coef"), ("entropy_coeff","ent_coef"), ("lr", "learning_rate"), ("grad_clip", "max_grad_norm")] + valid_schedulers = ["linear", "constant", "double_linear_con", "middle_drop","double_middle_drop"] + if("lr_schedule" in agent_config.keys()): + if(agent_config["lr_schedule"] in valid_schedulers): + valid_keys.append("lr_schedule") + # all schedulers must be valid + if("lr_schedule" in var_agent_configs.keys()): + add = True + for scheduler in var_agent_configs["lr_schedule"]: + if(scheduler not in valid_schedulers): + add = False + if(add): + valid_keys.append("lr_schedule") + # -------- Change keys from Agent to Model dict when needed--------# for key_tuple in agent_to_model: old_key, new_key = key_tuple @@ -231,16 +249,12 @@ def agent_to_baselines(config): # change model_config to baselines framework/ decide MLP or CNN policy -def model_to_policy_kwargs(feat_ext, model_config): - # -------------- Model configuration ------------# - # # decide whether to use cnn or mlp, taken from ray code.. - # # Discrete/1D obs-spaces. - # if isinstance(env.observation_space, gym.spaces.Discrete) or \ - # len(env.observation_space.shape) <= 2: - # feat_ext = "mlp" - # else: # Default Conv2D net. - # feat_ext = "cnn" - +def model_to_policy_kwargs(env, model_config): + if(isinstance(env.observation_space, gym.spaces.Discrete) or \ + len(env.observation_space.shape) <= 2): + feat_ext = "mlp" + else: + feat_ext = "cnn" # Move model config(already on baselines framework) to policy_kwargs policy_kwargs, cnn_config = {}, {} for key in model_config["model"].keys(): @@ -266,10 +280,10 @@ def model_to_policy_kwargs(feat_ext, model_config): policy_kwargs['cnn_extractor'] = vision_net policy_kwargs["kwargs"] = cnn_config + if(feat_ext=="mlp" and "net_arch" in policy_kwargs): + policy_kwargs.pop("net_arch") + policy_kwargs['feature_extraction'] = feat_ext - # # add policy arguments to agent configuration - # if('lr_schedule'in agent_config.keys()): #schedule is part of model instead of agent in baselines - # agent_config['policy_kwargs']['lr_schedule'] = agent_config['lr_schedule'] return policy_kwargs, use_lstm @@ -288,27 +302,48 @@ def act_fnc_from_name(key): def vision_net(scaled_images, kwargs): if ("act_fun" in kwargs): activ_fn = kwargs['act_fun'] - else: #default + else: # default activ_fn = tf.nn.relu output, i = scaled_images, 0 for i, layer_def in enumerate(kwargs['net_arch'][:-1], start=1): n_filters, kernel, stride = layer_def - scope = "c%d"%(i) - output = activ_fn(conv(output, scope, n_filters = n_filters, filter_size = kernel[0], stride = stride, pad="SAME", init_scale=np.sqrt(2))) - - #last layer has valid padding + scope = "c%d" % (i) + output = activ_fn(conv(output, + scope, + n_filters=n_filters, + filter_size=kernel[0], + stride=stride, + pad="SAME", + init_scale=np.sqrt(2))) + + # last layer has valid padding n_filters, kernel, stride = kwargs['net_arch'][-1] - output = activ_fn(conv(output, scope = "c%d"%(i+1), n_filters = n_filters, filter_size = kernel[0], stride = stride, pad="VALID", init_scale=np.sqrt(2))) - output = conv_to_fc(output) #No linear layer - #output = activ_fn(linear(output, 'fc1', n_hidden=512, init_scale=np.sqrt(2))) + output = activ_fn(conv(output, + scope="c%d" % (i+1), + n_filters=n_filters, + filter_size=kernel[0], + stride=stride, + pad="VALID", + init_scale=np.sqrt(2))) + output = conv_to_fc(output) # No linear layer + # output = activ_fn(linear(output, 'fc1', n_hidden=512, init_scale=np.sqrt(2))) return output -def init_agent(env, config_algorithm, agent_config_baselines, use_lstm): - #Use feed forward policies and specify cnn feature extractor in configuration +def init_agent(env, config_algorithm, model_cfg, agent_config_baselines): + policy_kwargs, use_lstm = \ + model_to_policy_kwargs(env, model_cfg) + # Change feature extractor depending on environment as in ray + agent_config_baselines["policy_kwargs"] = policy_kwargs + + # Use feed forward policies and + # specify cnn feature extractor in configuration if config_algorithm == 'DQN': - model = DQN(env = env, policy = sb.deepq.policies.FeedForwardPolicy, **agent_config_baselines, verbose=1) + model = DQN(env=env, + policy=sb.deepq.policies.FeedForwardPolicy, + **agent_config_baselines, + verbose=1) elif config_algorithm == 'DDPG': # action noise is none by default meaning it does not explore.. # condiguration using ray defaults @@ -317,16 +352,82 @@ def init_agent(env, config_algorithm, agent_config_baselines, use_lstm): agent_config_baselines["action_noise"] = OrnsteinUhlenbeckActionNoise( mean=np.zeros(n_actions),\ sigma=float(0.2) * np.ones(n_actions)) - #ddpg - #can also use as agent parameter "normalize_observations = True " or "normalize_returns" = True - model = DDPG(env = env, policy = sb.ddpg.policies.FeedForwardPolicy, **agent_config_baselines, verbose=1 ) + # ddpg + # can also use as agent parameter + # "normalize_observations = True " + # or "normalize_returns" = True + model = DDPG(env=env, + policy=sb.ddpg.policies.FeedForwardPolicy, + **agent_config_baselines, + verbose=1) elif config_algorithm == "TD3": - model = TD3(env = env, policy = sb.td3.policies.FeedForwardPolicy, **agent_config_baselines, verbose=1 ) + model = TD3(env=env, + policy=sb.td3.policies.FeedForwardPolicy, + **agent_config_baselines, + verbose=1) elif config_algorithm == "A3C" or config_algorithm == "A2C": - policy = sb.common.policies.LstmPolicy if use_lstm else sb.common.policies.FeedForwardPolicy - model = A2C(env = env, policy = policy ,**agent_config_baselines, verbose=1) - else: #'SAC - model = SAC(env = env, policy = sb.sac.policies.FeedForwardPolicy ,**agent_config_baselines, verbose=1) + policy = sb.common.policies.LstmPolicy if use_lstm \ + else sb.common.policies.FeedForwardPolicy + model = A2C(env=env, + policy=policy, + **agent_config_baselines, + verbose=1) + else: # 'SAC + model = SAC(env=env, + policy=sb.sac.policies.FeedForwardPolicy, + **agent_config_baselines, + verbose=1) + return model + + +def init_environments(config_algorithm, current_config, env_config, eval_cfg): + env_config = process_env_keys(env_config, + current_config) + env = gym.make(current_config['env'], + **env_config) + + # if time limit, wrap it + if("horizon" in current_config['env']): + train_horizon = current_config['env']["horizon"] + env = TimeLimit(env, max_episode_steps=train_horizon) # horizon + env = sb.bench.Monitor(env, None) # , "../", force=True) + # Automatically normalize the input features and reward + if (config_algorithm == "DDPG" + or config_algorithm == "A2C" + or config_algorithm == "A3C"): + env = DummyVecEnv([lambda: env]) + env = VecNormalize(env, + norm_obs=False, + norm_reward=True, + clip_obs=10.) + + # limit max timesteps in evaluation + eval_horizon = 100 + if("horizon" in eval_cfg): + eval_horizon = eval_cfg["horizon"] + eval_env = gym.make(current_config['env'], + **env_config) + eval_env = TimeLimit(eval_env, max_episode_steps=eval_horizon) + return env, eval_env + + +def process_env_keys(env_config, current_config): + dict_keys = list(env_config.keys()) + for key in dict_keys: + if key == 'reward_noise': + reward_noise_ = current_config["env_config"][key] + env_config[key] = lambda a: a.normal(0, reward_noise_) + env_config['reward_noise_std'] = reward_noise_ + elif key == 'transition_noise' and env_config["state_space_type"] == "continuous": + transition_noise_ = current_config["transition_noise"][key] + env_config[key] = lambda a: a.normal(0, transition_noise_) + env_config['transition_noise_std'] = transition_noise_ + + if("state_space_type" in env_config): + if env_config["state_space_type"] == 'continuous': + env_config["action_space_dim"] = env_config["state_space_dim"] + + return env_config class CustomCallback(sb.common.callbacks.BaseCallback): @@ -349,7 +450,7 @@ def __init__( verbose: int = 1, file_name: str = "./evaluation.csv", config_algorithm: str ="", - var_configs = None + var_configs=None ): super(CustomCallback, self).__init__(verbose=verbose) self.n_eval_episodes = n_eval_episodes @@ -440,21 +541,21 @@ def write_train_result(self): if isinstance(env, VecEnv): env = env.unwrapped.envs[0] # only using one environment - #A2C can handle multiple envs.. + # A2C can handle multiple envs.. # if(self.config_algorithm == "A2C" or self.config_algorithm =="A3C"): # env = env.envs[0]#take first env # Writes every iteration, would slow things down. #hack - fout = open(self.file_name + '.csv', 'a') #hardcoded + fout = open(self.file_name + '.csv', 'a') # hardcoded fout.write(str(training_iteration) + ' ' + config_algorithm + ' ') for config_type, config_dict in var_configs.items(): for key in config_dict: if config_type == "env": env_config = env.config if key == 'reward_noise': - fout.write(str(env_config['reward_noise_std']) + ' ') #hack + fout.write(str(env_config['reward_noise_std']) + ' ') # hack elif key == 'transition_noise' and env_config["state_space_type"] == "continuous": - fout.write(str(env_config['transition_noise_std']) + ' ') #hack + fout.write(str(env_config['transition_noise_std']) + ' ') # hack else: fout.write(str(env_config[key]).replace(' ', '') + ' ') elif config_type == "agent": @@ -474,7 +575,7 @@ def write_train_result(self): if(self.episodes_in_iter == 0): # no episodes in iteration if(n_episodes) == 0: # special case when there are no episodes so far episode_reward_mean = np.sum(env.rewards) # cummulative reward so far - episode_len_mean = env.get_total_steps() # all steps so far + episode_length_mean = env.get_total_steps() # all steps so far else: # iteration end, no episode end # start = self.timesteps_per_iteration*training_iteration diff --git a/mdp_playground/config_processor/config_processor_old.py b/mdp_playground/config_processor/config_processor.py similarity index 51% rename from mdp_playground/config_processor/config_processor_old.py rename to mdp_playground/config_processor/config_processor.py index 523bc21..aa553bc 100644 --- a/mdp_playground/config_processor/config_processor_old.py +++ b/mdp_playground/config_processor/config_processor.py @@ -1,12 +1,246 @@ - -from os import stat -from numpy.core.fromnumeric import var from ray.tune.registry import register_env from .baselines_processor import agent_to_baselines, model_to_policy_kwargs import copy +import sys, os +import collections mujoco_envs = ["HalfCheetahWrapper-v3", "HopperWrapper-v3", "PusherWrapper-v2", "ReacherWrapper-v2"] +import mdp_playground +from mdp_playground.envs import RLToyEnv +from ray.tune.registry import register_env +register_env("RLToy-v0", lambda config: RLToyEnv(**config)) +register_env("GymEnvWrapper-Atari", lambda config: create_gym_env_wrapper_atari(config)) +register_env("GymEnvWrapperFrameStack-Atari", lambda config: create_gym_env_wrapper_frame_stack_atari(config)) + +from ray.rllib.models.preprocessors import OneHotPreprocessor +from ray.rllib.models import ModelCatalog +ModelCatalog.register_custom_preprocessor("ohe", OneHotPreprocessor) + + +def process_configs(config_file, stats_file_prefix, config_num, log_level, framework='ray'): + config_file_path = os.path.abspath('/'.join(config_file.split('/')[:-1])) + + sys.path.insert(1, config_file_path) # hack + import importlib + config = importlib.import_module(config_file.split('/')[-1], package=None) + print("Number of seeds for environment:", config.num_seeds) + + + # hacks needed to setup Ray callbacks below + var_configs_deepcopy = copy.deepcopy(config.var_configs) # hack because this needs to be read in on_train_result and trying to read config there raises an error because it's been imported from a Python module and I think they try to reload it there. + if "timesteps_total" in dir(config): + hacky_timesteps_total = config.timesteps_total # hack + + config_algorithm = config.algorithm # hack + # sys.exit(0) + + columns_to_write = [] + for config_type, config_dict in var_configs_deepcopy.items(): + for key in config_dict: + columns_to_write.append(key) + + stats_file_name = stats_file_prefix + '.csv' + + init_stats_file(stats_file_name, columns_to_write) + + # Ray specific setup: + if framework.lower() == 'ray': + from ray import tune + setup_ray(config, config_num, log_level) + on_train_result, on_episode_end = setup_ray_callbacks(stats_file_prefix, var_configs_deepcopy, hacky_timesteps_total, config_algorithm) + + # default Define default config which gets overwritten with config in config.py file if present. + default_config = { + "callbacks": { + # "on_episode_start": tune.function(on_episode_start), + # "on_episode_step": tune.function(on_episode_step), + "on_episode_end": tune.function(on_episode_end), + # "on_sample_end": tune.function(on_sample_end), + "on_train_result": tune.function(on_train_result), + # "on_postprocess_traj": tune.function(on_postprocess_traj), + }, + # "log_level": 'WARN', + } + + # Stable Baselines specific setup: + elif framework.lower() == 'stable_baselines': + cfg = (config.algorithm, + config.agent_config, + config.model_config, + config.var_configs) + agent_config, model_config, var_agent_configs, var_model_configs = \ + agent_to_baselines(cfg) + config.agent_config = agent_config + config.model_config = model_config + config.var_agent_configs = var_agent_configs + config.var_model_configs = var_model_configs + var_env_configs = collections.OrderedDict() + if("env" in var_configs_deepcopy): + var_env_configs = var_configs_deepcopy["env"] + var_configs_deepcopy = {"agent": collections.OrderedDict(var_agent_configs), + "model": collections.OrderedDict(var_model_configs), + "env": var_env_configs} + + default_config = {"stats_file_name": stats_file_name, + "var_configs_deepcopy": var_configs_deepcopy} + else: + raise ValueError("Framework passed was not a valid option. It was: " + framework + ". Available options are: ray and stable_baselines.") + + + varying_configs = get_grid_of_configs(config.var_configs) + # print("VARYING_CONFIGS:", varying_configs) + + final_configs = combined_processing(default_config, config.env_config, config.agent_config, config.model_config, config.eval_config, varying_configs=varying_configs, framework=framework, algorithm=config.algorithm) + + return config, final_configs + + +def setup_ray(config, config_num, log_level): + import ray + if config.algorithm == 'DQN': #hack + ray.init(object_store_memory=int(2e9), redis_max_memory=int(1e9), temp_dir='/tmp/ray' + str(config_num), include_webui=False, logging_level=log_level, local_mode=True) #webui_host='0.0.0.0'); logging_level=logging.INFO, #hardcoded + + # ray.init(object_store_memory=int(2e9), redis_max_memory=int(1e9), local_mode=True, plasma_directory='/tmp') #, memory=int(8e9), local_mode=True # local_mode (bool): If true, the code will be executed serially. This is useful for debugging. # when true on_train_result and on_episode_end operate in the same current directory as the script. A3C is crashing in local mode, so didn't use it and had to work around by giving full path + filename in stats_file_name.; also has argument driver_object_store_memory=, plasma_directory='/tmp' + elif config.algorithm == 'A3C': #hack + ray.init(object_store_memory=int(2e9), redis_max_memory=int(1e9), temp_dir='/tmp/ray' + str(config_num), include_webui=False, logging_level=log_level) + # ray.init(object_store_memory=int(2e9), redis_max_memory=int(1e9), local_mode=True, plasma_directory='/tmp') + else: + ray.init(object_store_memory=int(2e9), redis_max_memory=int(1e9), local_mode=True, temp_dir='/tmp/ray' + str(config_num), include_webui=False, logging_level=log_level) + + +def init_stats_file(stats_file_name, columns_to_write): + fout = open(stats_file_name, 'a') #hardcoded + fout.write('# training_iteration, algorithm, ') + for column in columns_to_write: + # if config_type == "agent": + # if config_algorithm == 'SAC' and key == "critic_learning_rate": + # real_key = "lr" #hack due to Ray's weird ConfigSpaces + # fout.write(real_key + ', ') + # elif config_algorithm == 'SAC' and key == "fcnet_hiddens": + # #hack due to Ray's weird ConfigSpaces + # fout.write('fcnet_hiddens' + ', ') + # else: + # fout.write(key + ', ') + # else: + fout.write(column + ', ') + fout.write('timesteps_total, episode_reward_mean, episode_len_mean\n') + fout.close() + +def setup_ray_callbacks(stats_file_prefix, var_configs_deepcopy, hacky_timesteps_total, config_algorithm): + # Setup Ray callbacks + # Ray callback to write training stats to CSV file at end of every training iteration + #hack Didn't know how to move this function to config. It requires the filename which _has_ to be possible to set in run_experiments.py. Had to take care of stats_file_prefix, var_configs_deepcopy, hacky_timesteps_total, config_algorithm; and had to initialise file writing in here (config_processor). + def on_train_result(info): + training_iteration = info["result"]["training_iteration"] + # algorithm = info["trainer"]._name + + # Writes every iteration, would slow things down. #hack + fout = open(stats_file_prefix + '.csv', 'a') #hardcoded + fout.write(str(training_iteration) + ' ' + config_algorithm + ' ') + for config_type, config_dict in var_configs_deepcopy.items(): + for key in config_dict: + if config_type == "env": + field_val = info["result"]["config"]["env_config"][key] + if isinstance(field_val, float): + str_to_write = '%.2e' % field_val + elif type(field_val) == list: + str_to_write = "[" + for elem in field_val: + # print(key) + str_to_write += '%.2e' % elem if isinstance(elem, float) else str(elem) + str_to_write += "," + str_to_write += "]" + else: + str_to_write = str(field_val).replace(' ', '') + str_to_write += ' ' + fout.write(str_to_write) + elif config_type == "agent": + if config_algorithm == 'SAC' and key == "critic_learning_rate": + real_key = "lr" #hack due to Ray's weird ConfigSpaces + fout.write('%.2e' % info["result"]["config"]['optimization'][key].replace(' ', '') + ' ') + elif config_algorithm == 'SAC' and key == "fcnet_hiddens": + #hack due to Ray's weird ConfigSpaces + str_to_write = str(info["result"]["config"]["Q_model"][key]).replace(' ', '') + ' ' + fout.write(str_to_write) + # elif config_algorithm == 'SAC' and key == "policy_model": + # #hack due to Ray's weird ConfigSpaces + # pass + # fout.write(str(info["result"]["config"][key]['fcnet_hiddens']).replace(' ', '') + ' ') + else: + if key == "exploration_fraction" and "exploration_fraction" not in info["result"]["config"]: #hack ray 0.7.3 will have exploration_fraction but not versions later than ~0.9 + field_val = info["result"]["config"]["exploration_config"]["epsilon_timesteps"] / hacky_timesteps_total # convert to fraction to be similar to old exploration_fraction + else: + field_val = info["result"]["config"][key] + str_to_write = '%.2e' % field_val if isinstance(field_val, float) else str(field_val).replace(' ', '') + str_to_write += ' ' + fout.write(str_to_write) + elif config_type == "model": + # if key == 'conv_filters': + fout.write(str(info["result"]["config"]["model"][key]).replace(' ', '') + ' ') + + # Write train stats + timesteps_total = info["result"]["timesteps_total"] # also has episodes_total and training_iteration + episode_reward_mean = info["result"]["episode_reward_mean"] # also has max and min + # print("Custom_metrics: ", info["result"]["step_reward_mean"], info["result"]["step_reward_max"], info["result"]["step_reward_min"]) + episode_len_mean = info["result"]["episode_len_mean"] + + fout.write(str(timesteps_total) + ' ' + '%.2e' % episode_reward_mean + + ' ' + '%.2e' % episode_len_mean + '\n') # timesteps_total always HAS to be the 1st written: analysis.py depends on it + fout.close() + + # print("##### stats_file_name: ", stats_file_name) + # print(os.getcwd()) + + # We did not manage to find an easy way to log evaluation stats for Ray without the following hack which demarcates the end of a training iteration in the evaluation stats file + stats_file_eval = stats_file_prefix + '_eval.csv' + fout = open(stats_file_eval, 'a') #hardcoded + + import os, psutil + mem_used_mb = psutil.Process(os.getpid()).memory_info().rss / 1024 ** 2 + + fout.write('#HACK STRING EVAL, mem_used_mb: ' + str(mem_used_mb) + "\n") + fout.close() + + info["result"]["callback_ok"] = True + + + # Ray callback to write evaluation stats to CSV file at end of every training iteration + # on_episode_end is used because these results won't be available on_train_result + # but only after every episode has ended during evaluation (evaluation phase is + # checked for by using dummy_eval) + def on_episode_end(info): + if "dummy_eval" in info["env"].get_unwrapped()[0].config: + # print("###on_episode_end info", info["env"].get_unwrapped()[0].config["make_denser"], info["episode"].total_reward, info["episode"].length) #, info["episode"]._agent_reward_history) + reward_this_episode = info["episode"].total_reward + length_this_episode = info["episode"].length + stats_file_eval = stats_file_prefix + '_eval.csv' + fout = open(stats_file_eval, 'a') #hardcoded + fout.write('%.2e' % reward_this_episode + ' ' + str(length_this_episode) + "\n") + fout.close() + + def on_episode_step(info): + episode = info["episode"] + if "step_reward" not in episode.custom_metrics: + episode.custom_metrics["step_reward"] = [] + step_reward = episode.total_reward + else: + step_reward = episode.total_reward - np.sum(episode.custom_metrics["step_reward"]) + episode.custom_metrics["step_reward"].append(step_reward) # This line + # should not be executed the 1st time this function is called because + # no step has actually taken place then (Ray 0.9.0)!! + # episode.custom_metrics = {} + # episode.user_data = {} + # episode.hist_data = {} + # Next 2 are the same, except 1st one is total episodic reward _per_ agent + # episode.agent_rewards = defaultdict(float) + # episode.total_reward += reward + # only hack to get per step reward seems to be to store prev total_reward + # and subtract it from that + # episode._agent_reward_history[agent_id].append(reward) + + return on_train_result, on_episode_end + def get_grid_of_configs(var_configs): ''' var_configs: dict of dicts of lists as values @@ -56,7 +290,6 @@ def get_grid_of_configs(var_configs): return grid_of_configs - def combined_processing(*static_configs, varying_configs, framework='ray', algorithm): ''' varying_configs is a dict of dicts with structure: { @@ -73,42 +306,31 @@ def combined_processing(*static_configs, varying_configs, framework='ray', algor varying_config = {"env_config": varying_config["env"], **varying_config["agent"], "model": varying_config["model"]} varying_configs[i] = varying_config + # Ray specific pre-processing if framework.lower() == 'ray': ... + # Stable Baselines specific pre-processing elif framework.lower() == 'stable_baselines': - env_cfg, agent_cfg, model_cfg, eval_cfg = static_configs - static_configs = list(static_configs) - # Change variable configuration keys + default, env_cfg, agent_cfg, model_cfg, eval_cfg = static_configs + static_configs = (default, env_cfg, + {"agent": agent_cfg}, + {"model": model_cfg}, + {"evaluation": eval_cfg}) for i, cfg_dict in enumerate(varying_configs): var_cfg = cfg_dict.copy() var_env_cfg = var_cfg.pop('env_config') - var_model_cfg = var_cfg.pop('model') - cfg = {"model": var_model_cfg, - "agent": var_cfg} - # make agent and model static empty configs - curr_cfg = (algorithm, {}, {}, cfg) - # algorithm, agent_config, model_config, var_configs - _, _, var_agent_configs, var_model_configs =\ - agent_to_baselines(curr_cfg) + var_model_configs = var_cfg.pop('model') varying_configs[i] = {} varying_configs[i]["env_config"] = var_env_cfg varying_configs[i]["model"] = var_model_configs - varying_configs[i]["agent"] = var_agent_configs - # Change static configuration keys - # Make variable empty configs - curr_cfg = (algorithm, agent_cfg, model_cfg, {}) - agent_config, model_config, _, _ = agent_to_baselines(curr_cfg) - static_configs = (env_cfg, - {"agent": agent_config}, - {"model": model_config}, - eval_cfg) - static_configs = tuple(static_configs) + varying_configs[i]["agent"] = var_cfg else: raise ValueError("Framework passed was not a valid option. It was: " + framework + ". Available options are: ray and stable_baselines.") + # Merge all configs into one final_configs = [] for i in range(len(varying_configs)): @@ -117,6 +339,7 @@ def combined_processing(*static_configs, varying_configs, framework='ray', algor merged_conf = deepmerge_multiple_dicts(*static_configs_copy, varying_configs[i]) final_configs.append(merged_conf) # varying_configs, env_config, agent_config, eval_config + # Post-processing common to frameworks: for i, final_config in enumerate(final_configs): if final_configs[i]["env"] in mujoco_envs: @@ -189,6 +412,7 @@ def combined_processing(*static_configs, varying_configs, framework='ray', algor timesteps_total /= final_configs[i]["env_config"]["time_unit"] timesteps_total = int(timesteps_total) + final_configs[i]["timesteps_total"] = timesteps_total # Post-processing for Ray: @@ -199,13 +423,13 @@ def combined_processing(*static_configs, varying_configs, framework='ray', algor value = final_configs[i][key] if algorithm == 'SAC': - if key == 'critic_learning_rate': # hack + if key == 'critic_learning_rate': # hack final_configs[i]['optimization'] = { key: value, 'actor_learning_rate': value, 'entropy_learning_rate': value, } - if key == 'fcnet_hiddens': #hack + if key == 'fcnet_hiddens': # hack final_configs[i]['Q_model'] = { key: value, "fcnet_activation": "relu", @@ -228,22 +452,17 @@ def combined_processing(*static_configs, varying_configs, framework='ray', algor elif key == "model": for key_2 in final_configs[i][key]: if key_2 == "use_lstm": - final_configs[i][key][key_2]["max_seq_len"] = final_configs[i]["env"]["env_config"]["delay"] + final_configs[i]["env"]["env_config"]["sequence_length"] + 1 + final_configs[i][key]["max_seq_len"] = final_configs[i]["env_config"]["delay"] + final_configs[i]["env_config"]["sequence_length"] + 1 + # Post-processing for Stable Baselines: elif framework.lower() == 'stable_baselines': ts_k = "timesteps_per_iteration" for i, config in enumerate(final_configs): model_config = config["model"] - use_cnn = False - if("feature_extraction" in config["agent"]["policy_kwargs"]): - if config["agent"]["policy_kwargs"]["feature_extraction"] == "cnn": - use_cnn = True - feat_ext = 'mlp' if config["env_config"]["state_space_type"] == "discrete" \ - and not use_cnn else 'cnn' - policy_kwargs, use_lstm = \ - model_to_policy_kwargs(feat_ext, model_config) # return policy_kwargs - config["agent"]["policy_kwargs"].update(policy_kwargs) + use_lstm = False + if("use_lstm" in model_config["model"]): + use_lstm = model_config["model"]["use_lstm"] if(ts_k in config["agent"]): # this is not part of baselines parameters, need to separate timesteps_per_iteration = config["agent"].pop(ts_k) @@ -255,8 +474,6 @@ def combined_processing(*static_configs, varying_configs, framework='ray', algor return final_configs -###TODO **extra_config} - def create_gym_env_wrapper_mujoco_wrapper(config, wrapped_mujoco_env): '''Creates a GymEnvWrapper around a MujocoEnvWrapper ''' @@ -278,8 +495,10 @@ def deepmerge_multiple_dicts(*configs): from functools import reduce -def deepmerge(a, b, path=None): +def deepmerge(a, b, path=None, overwrite=True): '''Merges dict b into dict a + overwrite : bool + Overwrites value in a with value in b if True with a warning, else raises Exception Based on: https://stackoverflow.com/questions/7204805/how-to-merge-dictionaries-of-dictionaries/7205107#7205107 ''' if path is None: path = [] @@ -290,16 +509,16 @@ def deepmerge(a, b, path=None): elif a[key] == b[key]: pass # same leaf value else: - raise Exception('Conflict at %s' % '.'.join(path + [str(key)])) + if overwrite: + a[key] = b[key] + warnings.warn("Overwrote value " + str(a[key]) + " with " + str(b[key]) + " while merging dicts.") + else: + raise Exception('Conflict at %s' % '.'.join(path + [str(key)])) else: a[key] = b[key] return a -import mdp_playground -from mdp_playground.envs import RLToyEnv -from ray.tune.registry import register_env -register_env("RLToy-v0", lambda config: RLToyEnv(**config)) def create_gym_env_wrapper_atari(config): from gym.envs.atari import AtariEnv @@ -308,8 +527,6 @@ def create_gym_env_wrapper_atari(config): gew = GymEnvWrapper(ae, **config) ##IMP Had initially thought to put this config in config["GymEnvWrapper"] but because of code below which converts var_env_configs to env_config, it's best to leave those configs as top level configs in the dict! return gew -register_env("GymEnvWrapper-Atari", lambda config: create_gym_env_wrapper_atari(config)) - def create_gym_env_wrapper_frame_stack_atari(config): #hack ###TODO remove? '''When using frameStack GymEnvWrapper should wrap AtariEnv using wrap_deepmind_ray and therefore this function sets "wrap_deepmind_ray": True and 'frame_skip': 1 inside config so as to keep config same as for create_gym_env_wrapper_atari above and reduce manual errors when switching between the 2. @@ -323,6 +540,4 @@ def create_gym_env_wrapper_frame_stack_atari(config): #hack ###TODO remove? game = ''.join([g.capitalize() for g in game.split('_')]) ae = gym.make('{}NoFrameskip-v4'.format(game)) gew = GymEnvWrapper(ae, **config) ##IMP Had initially thought to put this config in config["GymEnvWrapper"] but because of code below which converts var_env_configs to env_config, it's best to leave those configs as top level configs in the dict! - return gew - -register_env("GymEnvWrapperFrameStack-Atari", lambda config: create_gym_env_wrapper_frame_stack_atari(config)) \ No newline at end of file + return gew \ No newline at end of file diff --git a/run_experiments_baselines.py b/run_experiments_baselines.py index 5842f11..1eca51e 100644 --- a/run_experiments_baselines.py +++ b/run_experiments_baselines.py @@ -5,6 +5,7 @@ from __future__ import absolute_import from __future__ import division from __future__ import print_function +from typing_extensions import final import numpy as np import copy @@ -14,23 +15,18 @@ import sys, os import argparse -import importlib - import default_config print("default_config:", default_config) import gym from gym.wrappers.time_limit import TimeLimit -#from gym.wrappers.monitor import Monitor -import stable_baselines as sb -from stable_baselines import DQN, DDPG, SAC, A2C, TD3 -from stable_baselines.common.noise import OrnsteinUhlenbeckActionNoise -from stable_baselines.common.vec_env import DummyVecEnv, VecNormalize import time import pprint +import mdp_playground.config_processor.config_processor as config_processor from mdp_playground.config_processor.baselines_processor import * - +import logging +log_level_ = logging.WARNING def parse_args(): parser = argparse.ArgumentParser(description=__doc__) # docstring at beginning of the file is stored in __doc__ @@ -48,175 +44,73 @@ def parse_args(): return args -def process_dictionaries(config, current_config, var_env_configs, var_agent_configs, var_model_configs): - algorithm = config.algorithm - agent_config = config.agent_config - model_config = config.model_config - env_config = config.env_config - - for config_type, config_dict in config.var_configs.items(): - for key in config_dict: - if config_type == "env": - if key == 'reward_noise': - reward_noise_ = current_config[list(var_env_configs).index(key)] # this works because env_configs are 1st in the OrderedDict - env_config["env_config"][key] = lambda a: a.normal(0, reward_noise_) - env_config["env_config"]['reward_noise_std'] = reward_noise_ #hack Needed to be able to write scalar value of std dev. to stats file instead of the lambda function above ###TODO Could remove the hack by creating a class for the noises and changing its repr() - elif key == 'transition_noise' and env_config["env_config"]["state_space_type"] == "continuous": - transition_noise_ = current_config[list(var_env_configs).index(key)] - env_config["env_config"][key] = lambda a: a.normal(0, transition_noise_) - env_config["env_config"]['transition_noise_std'] = transition_noise_ #hack - else: - env_config["env_config"][key] = current_config[list(var_env_configs).index(key)] - - elif config_type == "agent": - num_configs_done = len(list(var_env_configs)) - # if algorithm == 'SAC' and key == 'learning_rate': #hack - # pass - # value = current_config[num_configs_done + list(config.var_configs[config_type]).index(key)] - # agent_config['optimization'] = { - # key: value, - # 'actor_learning_rate': value, - # 'entropy_learning_rate': value, - # } - # elif algorithm == 'SAC' and key == 'layers': #hack - # agent_config['Q_model'] = { - # key: current_config[num_configs_done + list(config.var_configs[config_type]).index(key)], - # "fcnet_activation": "relu", - # } - # agent_config['policy_model'] = { - # key: current_config[num_configs_done + list(config.var_configs[config_type]).index(key)], - # "fcnet_activation": "relu", - # } - # else: - agent_config[key] = current_config[num_configs_done + list(config.var_configs[config_type]).index(key)] - - elif config_type == "model": - num_configs_done = len(list(var_env_configs)) + len(list(var_agent_configs)) - model_config["model"][key] = current_config[num_configs_done + list(config.var_configs[config_type]).index(key)] - - #hacks begin: - # if "use_lstm" in model_config["model"]: - # if model_config["model"]["use_lstm"]:#if true - # model_config["model"]["max_seq_len"] = env_config["env_config"]["delay"] + env_config["env_config"]["sequence_length"] + 1 - - if algorithm == 'TD3': - if("target_policy_noise" in agent_config): - agent_config["target_noise_clip"] = agent_config["target_noise_clip"] * agent_config["target_policy_noise"] - if("state_space_type" in env_config["env_config"]): - if env_config["env_config"]["state_space_type"] == 'continuous': - env_config["env_config"]["action_space_dim"] = env_config["env_config"]["state_space_dim"] - - return agent_config, model_config, env_config - - def main(args): # print("Config file", os.path.abspath(args.config_file)) # 'experiments/dqn_seq_del.py' if args.config_file[-3:] == '.py': - args.config_file = args.config_file[:-3] - - config_file_path = os.path.abspath('/'.join(args.config_file.split('/')[:-1])) - print("config_file_path:", config_file_path) - - sys.path.insert(1, config_file_path) #hack - config = importlib.import_module(args.config_file.split('/')[-1], package=None) - print("Number of seeds for environment:", config.num_seeds) - print("Configuration numbers that will be run:", "all" if args.config_num is None else args.config_num) + config_file = args.config_file[:-3] + else: + config_file = args.config_file - args.exp_name = os.path.abspath(args.exp_name) + stats_file_name = os.path.abspath(args.exp_name) if args.config_num is None: stats_file_name = args.exp_name else: stats_file_name = args.exp_name + '_' + str(args.config_num) print("Stats file being written to:", stats_file_name) - # ------------------------- Variable configurations ----------------------------# - config, var_agent_configs, var_model_configs = agent_to_baselines(config) - var_configs_deepcopy = copy.deepcopy(config.var_configs) #hack because this needs to be read in on_train_result and trying to read config there raises an error because it's been imported from a Python module and I think they try to reload it there. + # config_file_path = os.path.abspath('/'.join(args.config_file.split('/')[:-1])) + # print("config_file_path:", config_file_path) - if "env" in config.var_configs: - var_env_configs = config.var_configs["env"] #hack - else: - var_env_configs = [] - config_algorithm = config.algorithm #hack, used on on_train_result - - print('# Algorithm, state_space_size, action_space_size, delay, sequence_length, reward_density, make_denser, terminal_state_density, transition_noise, reward_noise ') - - configs_to_print = '' - for config_type, config_dict in var_configs_deepcopy.items(): - if config_type == 'env': - for key in config_dict: - configs_to_print += str(config_dict[key]) + ', ' - - print(config_algorithm, configs_to_print) - - #----------------- Write headers to csv file --------------------# - hack_filename = stats_file_name + '.csv' - fout = open(hack_filename, 'a') #hardcoded - fout.write('# training_iteration, algorithm, ') - for config_type, config_dict in var_configs_deepcopy.items(): - for key in config_dict: - fout.write(key + ', ') - fout.write('timesteps_total, episode_reward_mean, episode_len_mean\n') - fout.close() - - #---------- Compute cartesian product of configs ----------------# - start = time.time() - if args.config_num is None: - cartesian_product_configs = config.final_configs - else: - cartesian_product_configs = [config.final_configs[args.config_num]] + # sys.path.insert(1, config_file_path) # hack + # config = importlib.import_module(args.config_file.split('/')[-1], package=None) + # print("Number of seeds for environment:", config.num_seeds) + # print("Configuration numbers that will be run:", "all" if args.config_num is None else args.config_num) + + config, final_configs = \ + config_processor.process_configs(config_file, + stats_file_prefix=stats_file_name, + framework="stable_baselines", + config_num=args.config_num, + log_level=log_level_) + # ------------------------- Variable configurations ----------------------------# + print("Configuration number(s) that will be run:", "all" if args.config_num is None else args.config_num) # ------------ Run every configuration ------------------ # pp = pprint.PrettyPrinter(indent=4) - for i, current_config in enumerate(cartesian_product_configs): + total_configs = len(final_configs) + config_algorithm = config.algorithm + eval_cfg = config.eval_config + for i, current_config in enumerate(final_configs): print("Configuration: %d \t %d remaining" - % (i, len(cartesian_product_configs) - i)) - # ------------ Dictionaries setup ------------------ # - agent_config, model_config, env_config = \ - process_dictionaries(config, current_config, var_env_configs, var_agent_configs, var_model_configs) # hacks + % (i, total_configs - i)) # ------------ Env init ------------------ # - env = gym.make(current_config['env'], - **current_config['env_config']) - - # if time limit, wrap it - if("horizon" in current_config['env']): - train_horizon = current_config['env']["horizon"] - env = TimeLimit(env, max_episode_steps=train_horizon) # horizon - env = sb.bench.Monitor(env, None) # , "../", force=True) - # Automatically normalize the input features and reward - if (config_algorithm == "DDPG" - or config_algorithm == "A2C" - or config_algorithm == "A3C"): - env = DummyVecEnv([lambda: env]) - env = VecNormalize(env, - norm_obs=False, - norm_reward=True, - clip_obs=10.) - - # limit max timesteps in evaluation - eval_horizon = 100 - eval_env = gym.make(env_config['env'], **env_config['env_config']) - eval_env = TimeLimit(eval_env, max_episode_steps=eval_horizon) + env_config = current_config['env_config'] print("Env config:",) pp.pprint(env_config) - - #------------ Agent init ------------------ # + env, eval_env = \ + init_environments(config_algorithm, + current_config, + env_config, + eval_cfg["evaluation_config"]) + # ------------ Agent init ------------------ # # Create the agent timesteps_per_iteration = current_config["timesteps_per_iteration"] - use_lstm = current_config["use_lstm"] - agent_config_baselines = current_config["agent"] model = init_agent(env, config_algorithm, - agent_config_baselines, use_lstm) + current_config["model"], + current_config["agent"]) - #------------ train/evaluation ------------------ # + # ------------ train/evaluation ------------------ # timesteps_total = config.timesteps_total # train your model for n_iter timesteps - #Define evaluation - eval_interval = config.evaluation_interval # every x training iterations + # Define evaluation + # every x training iterations + eval_interval = eval_cfg["evaluation_interval"] + stats_file_name = current_config["stats_file_name"] + var_configs_deepcopy = current_config["var_configs_deepcopy"] csv_callbacks = CustomCallback(eval_env, n_eval_episodes=10, timesteps_per_iteration=timesteps_per_iteration, @@ -225,20 +119,23 @@ def main(args): file_name=stats_file_name, config_algorithm=config_algorithm, var_configs=var_configs_deepcopy) - #Train + # Train learn_params = {"callback": csv_callbacks, "total_timesteps": int(timesteps_total)} - if(config_algorithm == "DDPG"): #Log interval is handled differently for each algorithm, e.g. each log_interval episodes(DQN) or log_interval steps(DDPG). + if(config_algorithm == "DDPG"): + # Log interval is handled differently for each algorithm, + # e.g. each log_interval episodes(DQN) or log_interval steps(DDPG). learn_params["log_interval"] = timesteps_per_iteration else: learn_params["log_interval"] = timesteps_per_iteration//10 - + model.learn(**learn_params) - model.save('%s_last'%(args.exp_name)) + model.save('%s_last' % (args.exp_name)) end = time.time() print("No. of seconds to run:", end - start) + if __name__ == '__main__': args = parse_args() - main(args) \ No newline at end of file + main(args) From f86c043323e474116f42ae928749594e931b304f Mon Sep 17 00:00:00 2001 From: Raghu Rajan Date: Fri, 1 Oct 2021 20:27:13 +0200 Subject: [PATCH 11/22] CAVE integration initial stuff from Jessica's branch --- config_readme.md | 163 - inspect_weights.py | 69 - mdp_playground/analysis/mdpp_to_cave.py | 70 +- .../config_processor/baselines_processor.py | 606 --- .../config_processor/config_processor.py | 543 --- plot_experiments.ipynb | 4174 +---------------- run_experiments.py | 58 - run_experiments_baselines.py | 141 - run_experiments_baselines3.py | 501 -- run_experiments_ray.py | 566 --- 10 files changed, 69 insertions(+), 6822 deletions(-) delete mode 100644 config_readme.md delete mode 100644 inspect_weights.py delete mode 100644 mdp_playground/config_processor/baselines_processor.py delete mode 100644 mdp_playground/config_processor/config_processor.py delete mode 100644 run_experiments.py delete mode 100644 run_experiments_baselines.py delete mode 100644 run_experiments_baselines3.py delete mode 100644 run_experiments_ray.py diff --git a/config_readme.md b/config_readme.md deleted file mode 100644 index 55e020b..0000000 --- a/config_readme.md +++ /dev/null @@ -1,163 +0,0 @@ -# Configuration Files - -Configuration files are an easy way to define the experiments to run in mdp-playground. They can be passed as command line arguments to run_experiments.py either by using `-c` or `--config-file` argument. The example below shows how to run the sequence length and delay experiment for dqn specifying the configuration file through the command line. This file must be a Python file. - - run_experiments.py -c ./experiments/dqn_seq_del.py - run_experiments.py --config-file ./experiments/dqn_seq_del.py - - There are 2 types of configurations across the experiments: - - Variable Config and - - Static Config - - ## Variable configurations - -Variable configurations allow you to define variables whose impact is desired to be studied. For instance one might be interested on the effect on the agents' performance when varying the `sequence_length` and `delay` meta-features for the current experiment. Then `delay` and `sequence_length` would be a key in `var_env_configs` dict and its corresponding value would be a *list of values they can take*. Then a cartesian product of these lists is taken to generate various possible configurations to be run. - - var_env_configs = OrderedDict({ - 'state_space_size': [8], - 'action_space_size': [8], - 'delay': [0] + [2**i for i in range(4)], - 'sequence_length': [1, 2, 3, 4], - 'reward_density': [0.25], - 'make_denser': [False], - 'terminal_state_density': [0.25], - 'transition_noise': [0], - 'reward_noise': [0], - 'dummy_seed': [i for i in range(num_seeds)] - }) - - var_configs = OrderedDict({ - "env": var_env_configs, - }) - -Variable configurations can be specified for either the environment, agent or the model across the current experiment. This can be specified through the OrderedDicts `var_env_configs`, `var_agent_configs` and `var_model_configs` configuration options respectively. - -Because Ray does not have a common way to address this specification of configurations for its agents, we offer the utility set `var_agent_configs` and `var_model_configs` the same way as `var_env_configs` is specified. - - var_configs = OrderedDict({ - "env": var_env_configs, - "agent": var_agent_configs, - "model" : var_model_configs - }) - - - Please see sample experiment config files in the experiments directory to see how to set the values for a given algorithm. - -## Static Configurations -`env_config`, `agent_config` and `model_config` are dictionaries which hold the static configuration for the current experiment as a normal Python dict. - -**Example**: - - env_config = { - "env": "RLToy-v0", - "horizon": 100, - "env_config": { - 'seed': 0, - 'state_space_type': 'discrete', - 'action_space_type': 'discrete', - 'generate_random_mdp': True, - 'repeats_in_sequences': False, - 'reward_scale': 1.0, - 'completely_connected': True, - }, - } -Please look into the code for details. - - -## API for agents -If you implement an agent and want to use our run_experiments.py out of the box then agent must follow the following API: -1. It should have a config that can be passed as dictionary -2. The configuration values of the **agent** should be specified as follows: - -### Exploration -* **schedule_max_timesteps (int):** -Max num timesteps for annealing schedules. Exploration is annealed from 1.0 to exploration_fraction over this number of timesteps scaled by exploration_fraction - -* **timesteps_per_iteration (int):** -Number of env steps to optimize for before returning - -* **exploration_fraction (float):** -Fraction of entire training period over which the exploration rate is annealed - -* **exploration_final_eps (float):** -Final value of random action probability - -* **target_network_update_freq (int):** -Update the target network every `target_network_update_freq` steps. - - -### Replay buffer configuration -* **buffer_size (int):** -Size of the replay buffer. - -* **prioritized_replay (bool):** -If True prioritized replay buffer will be used - -* **prioritized_replay_alpha (float):** -Alpha parameter for prioritized replay buffer - -* **prioritized_replay_beta (float):** -Beta parameter for sampling from prioritized replay buffer. - -* **beta_annealing_fraction (float):** -Fraction of entire training period over which the beta parameter is annealed. - -* **final_prioritized_replay_beta (float):** -Final value of beta - -* **prioritized_replay_eps (float):** -Epsilon to add to the TD errors when updating priorities. - -### Optimization: -* **lr (float):** -Learning rate for adam optimizer - -* **adam_epsilon (float):** -Adam epsilon hyper parameter - -* **grad_norm_clipping (float):** -If not None, clip gradients during optimization at this value. - -* **learning_starts (int):** -How many steps of the model to sample before learning starts. - -* **train_batch_size (int):** -Size of a batched sampled from replay buffer for training. Note that if async_updates is set, then each worker returns gradients for a batch of this size. - -### Execution: -* **num_envs_per_worker (int):** -Number of environments to evaluate vectorwise per worker. - -* **sample_batch_size (int):** -Default sample batch size (unroll length). Batches of this size are collected from workers until train_batch_size is met. When using multiple envs per worker, this is multiplied by num_envs_per_worker. The replay buffer is updated with this many samples at once. Note that this setting applies per-worker if num_workers > 1. - -* **train_batch_size (int):** -Size of a batched sampled from replay buffer for training. Note that if async_updates is set, then each worker returns gradients for a batch of this size. -Should be >= sample_batch_size. Samples batches will be concatenated together to this size for training. - - * **batch_mode (str):** -Whether to rollout "complete_episodes" or "truncate_episodes". - - * **sample_async (bool):** -Use a background thread for sampling (slightly off-policy) - -### DQN specifics: -* **noisy (bool):** -Whether to use noisy network - -* **dueling (bool):** -Whether to use dueling dqn - -* **double_q (bool):** -Whether to use double dqn - -* **hiddens ( [int] vector):** -Postprocess model outputs with these hidden layers to compute the state and action values. - -* **n_step (int):** -N-step Q learning - \ No newline at end of file diff --git a/inspect_weights.py b/inspect_weights.py deleted file mode 100644 index e825ca6..0000000 --- a/inspect_weights.py +++ /dev/null @@ -1,69 +0,0 @@ -import tensorflow as tf -import stable_baselines as sb -import matplotlib.pyplot as plt -from stable_baselines.common import BaseRLModel -from stable_baselines import DQN, DDPG, SAC, A2C, TD3 -import numpy as np -import argparse -import zipfile -import os -import sys -import gym - - -def parse_args(): - parser = argparse.ArgumentParser(description=__doc__) # docstring at beginning of the file is stored in __doc__ - parser.add_argument('-n', '--file-name', dest="filename", - help="full path where the stable baselines model is stored as a zip") - parser.add_argument('-s', '--save-dir', dest="save_dir", default="../tmp/", - help="Where to save the images") - args = parser.parse_args() - print("Parsed args:", args) - return args - - -def main(args): - env = gym.make('CartPole-v1') - model = A2C(sb.common.policies.MlpLstmPolicy, env) - # model.load(args.filename) - f_path = os.path.abspath(args.filename) - if(os.path.exists(f_path+".zip")): - _, params = model._load_from_file(f_path) - else: - print("Path does not exist: %s" % f_path) - return - - if(not os.path.exists(args.save_dir)): - os.makedirs(args.save_dir) - - w = tf.summary.FileWriter("../mdp_files/output/", model.graph) - - min_v, max_v = sys.maxsize, -sys.maxsize - 1 - for v in params.values(): - if(np.max(v) > max_v): - max_v = np.max(v) - elif(np.min(v) < min_v): - min_v = np.min(v) - - exp_name = os.path.abspath(args.filename).split(os.path.sep)[-1] - for k, v in params.items(): - if('w' in k): # weights - p_name = k.split('/')[1] - plt.suptitle(p_name + str(v.shape)) - plt.imshow(v, cmap="twilight") - # plt.show() - plt.clim(min_v, max_v) - plt.colorbar() - save_plot = os.path.join( - args.save_dir, - "%s_%s" % (exp_name, p_name)) - plt.savefig(save_plot, bbox_inches='tight', - pad_inches=0.0, dpi=200) - plt.clf() - plt.close() - return - - -if __name__ == '__main__': - args = parse_args() - main(args) diff --git a/mdp_playground/analysis/mdpp_to_cave.py b/mdp_playground/analysis/mdpp_to_cave.py index 6522f14..99218ba 100644 --- a/mdp_playground/analysis/mdpp_to_cave.py +++ b/mdp_playground/analysis/mdpp_to_cave.py @@ -1,5 +1,5 @@ import numpy as np -import pandas as pd +import pandas as pd import argparse, os import json @@ -15,7 +15,7 @@ def _create_configspace_json(self, stats_pd, var_configs): "json_format_version": 0.1} for param in var_configs: param_config = {"name": param} - var_type = str( type(stats_pd[param].iloc[0]) ) + var_type = str( type(stats_pd[param].iloc[0]) ) if("int" in var_type or "bool" in var_type): param_config["lower"] = int( stats_pd[param].min() ) param_config["upper"] = int( stats_pd[param].max() ) @@ -31,7 +31,7 @@ def _create_configspace_json(self, stats_pd, var_configs): param_config["upper"] = float( stats_pd[param].max() ) param_config["default"] = (param_config["lower"] + param_config["upper"])/2 param_config["type"] = "uniform_float" - + if "lr" in param: param_config["log"] = True else: @@ -65,7 +65,7 @@ def join_files(self, file_prefix, file_suffix): with open(file_prefix + file_suffix, 'ab') as combined_file: i = 0 num_diff_lines = [] - while True: + while True: if os.path.isfile(file_prefix + '_' + str(i) + file_suffix): with open(file_prefix + '_' + str(i) + file_suffix, 'rb') as curr_file: byte_string = curr_file.read() @@ -106,7 +106,7 @@ def to_cave_csv(self, args): stats_pd = pd.read_csv(stats_file + '.csv', skip_blank_lines=True,\ header=None, names = col_names, comment='#', sep=' ') remove_names = ["training_iteration", "algorithm", "seed"] - + parameters = col_names[:-3].copy()#All paramaters tracked in run for x in col_names: for name in remove_names: @@ -127,7 +127,7 @@ def to_cave_csv(self, args): output_configspace = os.path.join(output_folder,'configspace.json') with open(output_configspace, 'w') as fp: json.dump(configspace, fp, indent=2) - + scenario_str = "paramfile = ./configspace.json\nrun_obj = quality" output_configspace = os.path.join(output_folder,'scenario.txt') with open(output_configspace, 'w') as fp: @@ -137,21 +137,31 @@ def to_cave_csv(self, args): runhistory_df = self._create_run_history(stats_pd, seed_idx, col_names, output_folder, var_configs) runhistory_df.to_csv( os.path.join(output_folder,'runhistory.csv'), header=True, index=False) - ## Creates the bohb file from the mdpp output in the output_folder directory - ## this file can be fed into cave for analysis - def to_bohb_results(self, dir_name, exp_name, output_dir="../cave_output/"): - self.output_folder = output_dir - if not os.path.exists(self.output_folder): - print("Writing bohb to cave output to %s"%(os.path.abspath(output_dir))) - os.makedirs(self.output_folder) + def to_bohb_results(self, input_dir, exp_name, output_dir="../cave_output/", + overwrite=False): + '''Converts MDP Playground stats CSVs to BOHB format stats files: + configs.json, results.json, configspace.json, in output_dir/exp_name. + This file can be fed into cave for further analysis. + + exp_name : str + Should be the expt name from MDPP, i.e., the "prefix" of the CSV stats files. A sub-directory of output_dir is created with this name to store BOHB format stats files. + + Returns "/" + ''' + + print("Writing BOHB to cave output to %s"%(os.path.abspath(output_dir))) + if not os.path.exists(output_dir): + os.makedirs(output_dir) # file_path = args.file_path - output_folder = os.path.join(self.output_folder, exp_name) - if not os.path.exists(output_folder): - os.makedirs(output_folder) + output_dir_final = os.path.join(output_dir, exp_name) + if not os.path.exists(output_dir_final): + os.makedirs(output_dir_final) + + # Read current csvs ## - stats_file = os.path.join(dir_name, exp_name) + stats_file = os.path.join(input_dir, exp_name) stats_file = os.path.abspath(stats_file) self._read_stats(stats_file) with open(stats_file + '.csv') as file_: @@ -191,7 +201,7 @@ def to_bohb_results(self, dir_name, exp_name, output_dir="../cave_output/"): ##------------- Start converting csv ----------------## #configspace and scenario file configspace = self._create_configspace_json(stats_pd, var_configs) - output_configspace = os.path.join(output_folder,'configspace.json') + output_configspace = os.path.join(output_dir_final,'configspace.json') with open(output_configspace, 'w') as fp: json.dump(configspace, fp, indent=2) @@ -199,7 +209,7 @@ def to_bohb_results(self, dir_name, exp_name, output_dir="../cave_output/"): #Finding end configuration training diff_configs = stats_pd.iloc[final_rows_for_a_config] diff_configs = diff_configs.groupby(var_configs) - configs_mean = diff_configs.mean() + configs_mean = diff_configs.mean() diff_configs_results = [] #results.json diff_configs_lst = [] budget = stats_pd["timesteps_total"].iloc[final_rows_for_a_config[0]]#all have the same budget @@ -226,43 +236,43 @@ def to_bohb_results(self, dir_name, exp_name, output_dir="../cave_output/"): "started": float("%.2f"%(aux + 0.1)), "finished": float("%.2f"%(aux + 1)),} ] aux += 1.1 - results_dict = {"loss": -mean_reward.item(), + results_dict = {"loss": -mean_reward.item(), "info": {}} results_lst.append(results_dict) results_lst.append(None) diff_configs_results.append(results_lst) #configs.json - output_configs = os.path.join(output_folder,'configs.json') + output_configs = os.path.join(output_dir_final,'configs.json') with open(output_configs, 'w') as fout: for d in diff_configs_lst: json.dump(d, fout) fout.write('\n') #results.json - output_configs = os.path.join(output_folder,'results.json') + output_configs = os.path.join(output_dir_final,'results.json') with open(output_configs, 'w') as fout: for d in diff_configs_results: json.dump(d, fout) fout.write('\n') - return output_folder + return output_dir_final if __name__ == "__main__": - dir_name = '../mdp_files/' + input_dir = '../mdp_files/' exp_name = 'dqn_seq_del' - + from cave.cavefacade import CAVE import os # The converted mdpp csvs will be stored in output_dir output_dir = "../mdpp_to_cave" - mdpp_file = os.path.join(dir_name, exp_name) + mdpp_file = os.path.join(input_dir, exp_name) mdpp_cave = MDPPToCave() - cave_input_file = mdpp_cave.to_bohb_results(dir_name, exp_name, output_dir) + cave_input_file = mdpp_cave.to_bohb_results(input_dir, exp_name, output_dir) # cave_input_file = "../../../mdpp_to_cave/dqn_seq_del" - # Similarly, as an example, cave will ouput it's results + # Similarly, as an example, cave will ouput it's results # to the same directory as cave's input files cave_results = os.path.join(cave_input_file, "output") @@ -273,7 +283,7 @@ def to_bohb_results(self, dir_name, exp_name, output_dir="../cave_output/"): file_format = "BOHB", show_jupyter=True, ) - + # Common analysis cave.performance_table() cave.local_parameter_importance() @@ -292,4 +302,4 @@ def to_bohb_results(self, dir_name, exp_name, output_dir="../cave_output/"): # cave.plot_ecdf() # cave.plot_scatter() # cave.compare_default_incumbent() - # cave.overview_table() \ No newline at end of file + # cave.overview_table() diff --git a/mdp_playground/config_processor/baselines_processor.py b/mdp_playground/config_processor/baselines_processor.py deleted file mode 100644 index 89e72b7..0000000 --- a/mdp_playground/config_processor/baselines_processor.py +++ /dev/null @@ -1,606 +0,0 @@ - -from psutil import net_if_addrs -from stable_baselines.common.noise import NormalActionNoise, OrnsteinUhlenbeckActionNoise -import gym -from stable_baselines.common.tf_layers import conv, linear, conv_to_fc, lstm -import tensorflow as tf -import numpy as np -import stable_baselines as sb -from typing import Any, Dict, List, Optional, Union -from stable_baselines.common.vec_env import DummyVecEnv, VecEnv, sync_envs_normalization -from stable_baselines import DQN, DDPG, SAC, A2C, TD3 -from stable_baselines.common.vec_env import DummyVecEnv, VecNormalize -from gym.wrappers.time_limit import TimeLimit - -# change config.agent_config, -# config.var_model_config -# config.var_agent_config to baselines framework -def agent_to_baselines(config): - policy_kwargs = {} - algorithm, agent_config, model_config, var_configs = config - var_agent_configs, var_model_configs = {}, {} - if("agent" in var_configs): - var_agent_configs = var_configs["agent"] - if("model" in var_configs): - var_model_configs = var_configs["model"] - - - valid_keys = ["gamma", "buffer_size", "batch_size", "learning_starts", - "timesteps_per_iteration"] # common - agent_to_model = [] # none - # Check correct keys for each algorithm - if algorithm == 'DQN': - # change keys in dictionaries to something baselines understands - valid_keys += ["exploration_fraction", "exploration_final_eps", - "exploration_initial_eps", - "train_freq", "double_q", - "prioritized_replay", "prioritized_replay_alpha", - "param_noise", "learning_rate", - "target_network_update_freq"] - - exchange_keys = [('noisy', 'param_noise'), - ('lr', 'learning_rate'), - ('train_batch_size', 'batch_size'), - ("rollout_fragment_length", "train_freq")] - # Move dueling to policy parameters - agent_to_model += [("dueling", "dueling")] - elif algorithm == "DDPG": - # memory_policy can be used to select PER - # random_exploration, param_noise, action_noise parameters aditional - valid_keys += ["critic_lr", "actor_lr", "tau","critic_l2_reg",\ - "clip_norm", "nb_rollout_steps", "nb_train_steps"] - valid_keys.remove("learning_starts") # For some reason it's the only one that does not have this implemented - exchange_keys = [ - ('rollout_fragment_length','nb_rollout_steps'), - ("l2_reg", "critic_l2_reg"), - ("grad_norm_clipping", "clip_norm"), - ('train_batch_size', 'batch_size')] - # Because of how DDPG is implemented it will perform 100 rollout steps and then 50 train steps - # This needs to be changed s.t. it does one rollout step and one training step - agent_config["nb_rollout_steps"] = 1 - agent_config["nb_train_steps"] = 1 - agent_to_model+=[("actor_hiddens", "layers"),("critic_hiddens", "layers")]#cannot specify different nets - # SPECIAL CASE, learning rates SHOULD NOT be none :c - for key in ["critic_lr", "actor_lr"]: - key_not_none = agent_config.get(key) - if (key in agent_config): - if(not key_not_none): #key==none - agent_config.pop(key) #remove to get default value - - elif algorithm == "TD3": - # memory_policy can be used to select PER; policy is always smoothened - # random_exploration, param_noise, action_noise parameters aditional - valid_keys += ["learning_rate", "policy_delay","tau","train_freq","gradient_steps",\ - "target_policy_noise","target_noise_clip","action_noise"] - exchange_keys = [ - ("target_noise", "target_policy_noise"), - ("critic_lr", "learning_rate"), - ("actor_lr", "learning_rate"), - ('train_batch_size', 'batch_size')] - agent_to_model += [("actor_hiddens", "layers"),( "critic_hiddens", "layers")] - # SPECIAL CASE, learning rates SHOULD NOT be none :c - for key in ["critic_lr, actor_lr"]: - key_not_none = agent_config.get(key) - if (key in agent_config): - if(not key_not_none): - agent_config.pop(key) # remove to get default value - # Because of how TD3 is implemented it will perform 100 grad steps every 100 steps - # This needs to be changed s.t. it does one rollout step and one training step - agent_config["train_freq"] = 1 - agent_config["gradient_steps"] = 1 - # s.t. it clips actions between[-1,1] - agent_config["action_noise"] = NormalActionNoise(mean=0, sigma=0) - elif algorithm == "SAC": - valid_keys += ["learning_rate", "tau", "ent_coef", "train_freq", - "target_update_interval", "clip_norm", "target_entropy"] - exchange_keys = [ - ("rollout_fragment_length","train_freq"), - ("entropy_learning_rate","learning_rate"), # same learning rate for - ("critic_learning_rate", "learning_rate"), # entropy - ("actor_learning_rate", "learning_rate"), # actor and critic - ("target_network_update_freq","target_update_interval"), - ("grad_norm_clipping", "clip_norm"), - ('train_batch_size', 'batch_size')] - agent_to_model += [("fcnet_hiddens", "layers")] - # -------- Add init entropy coef ------------# - if("initial_alpha" in agent_config.keys()): - agent_config["ent_coef"] = "auto_%.3f"%agent_config["initial_alpha"] #idk why but that's how baselines initializes this thing.. - agent_config.pop("initial_alpha") - # var agent configs initial_alpha - # idk why but that's how baselines initializes this thing.. - if(var_agent_configs): - if("initial_alpha" in var_agent_configs): - var_agent_configs["ent_coef"] = ["auto_%.3f"%coef for coef in var_agent_configs["initial_alpha"]] - var_agent_configs.pop("initial_alpha") - # ----------- special case ---------# - # should be at least one - if("target_network_update_freq" in agent_config): - key_val = agent_config["target_network_update_freq"] - agent_config["target_network_update_freq"] = 1 if key_val <= 0 else key_val - # -------- Take things out of optimization ------------# - # Special case: Optimization - if("optimization" in agent_config): - for k in agent_config["optimization"].keys(): - key_value = agent_config["optimization"][k] - if(key_value): # not none - agent_config[k] = key_value - # -------- Take things out of Q-model and policy_model ------------# - # Can only specify one model for everything - for move_key in ["Q_model", "policy_model"]: - if(move_key in model_config): - if("model" not in model_config): # init - model_config["model"] = {} - for k in model_config[move_key].keys(): - model_config["model"][k] = model_config[move_key][k] - model_config.pop(move_key) # Remove from model_config - else: # A2C - algorithm = "A2C" - valid_keys += ["learning_rate", - "vf_coef", - "ent_coef", - "max_grad_norm"] # "lr_schedule" cannot be none - exchange_keys = [ - ("vf_loss_coeff","vf_coef"), - ("entropy_coeff","ent_coef"), - ("lr", "learning_rate"), - ("grad_clip", "max_grad_norm")] - - valid_schedulers = ["linear", "constant", "double_linear_con", "middle_drop","double_middle_drop"] - if("lr_schedule" in agent_config.keys()): - if(agent_config["lr_schedule"] in valid_schedulers): - valid_keys.append("lr_schedule") - # all schedulers must be valid - if("lr_schedule" in var_agent_configs.keys()): - add = True - for scheduler in var_agent_configs["lr_schedule"]: - if(scheduler not in valid_schedulers): - add = False - if(add): - valid_keys.append("lr_schedule") - - # -------- Change keys from Agent to Model dict when needed--------# - for key_tuple in agent_to_model: - old_key, new_key = key_tuple - # -------- Agent config --------# - key_exists = agent_config.get(old_key) - if key_exists: # If key exists and is not none - policy_kwargs[new_key] = agent_config.pop(old_key) # Move key to model config - # #-------- Var agent config --------# - key_exists = var_agent_configs.get(old_key) - if key_exists: # If key exists and is not none - var_model_configs[new_key] = var_agent_configs.pop(old_key) # Move key to model config - - if('fcnet_hiddens' in agent_config.keys()): - policy_kwargs['layers'] = agent_config['fcnet_hiddens'] - agent_config.pop('fcnet_hiddens') - - # -------- Agent config --------# - # change agent keys - for key_tuple in exchange_keys: - old_key, new_key = key_tuple - # -------- Agent config --------# - if(old_key in agent_config): - agent_config[new_key] = agent_config.pop(old_key) - # -------- Var agent config --------# - if(old_key in var_agent_configs): - var_agent_configs[new_key] = var_agent_configs.pop(old_key) - - # remove keys from dictionary which are not configurable by baselines - for key in list(agent_config.keys()): - if(key not in valid_keys): # delete invalid keys - agent_config.pop(key) - - # -------- Var agent config --------# - # remove keys from dictionary which are not configurable by baselines - for key in list(var_agent_configs.keys()): - if(key not in valid_keys):#delete invalid keys - var_agent_configs.pop(key) - - # ----------- Model config ----------------# - valid_keys = ["act_fun", "net_arch", "feature_extractor", "layers", "use_lstm","n_lstm"] - exchange_keys = [("fcnet_activation", "act_fun"), - ("conv_activation", "act_fun"), - ("actor_hidden_activation", "act_fun"), - ("actor_hidden_activation", "act_fun"), - ("fcnet_hiddens", "layers"), - ("actor_hiddens", "layers"), - ("critic_hiddens","layers"), - ("conv_filters", "net_arch"), - ("lstm_cell_size","n_lstm")] - - # change keys - feat_ext = 'mlp' - for key_tuple in exchange_keys: - old_key, new_key = key_tuple - # -------- model config --------# - if("model" in model_config): - if(old_key in model_config["model"]): - if(old_key == 'conv_filters'): - feat_ext = 'cnn' - model_config["model"][new_key] = model_config["model"].pop(old_key) - - # -------- Var model config --------# - if(old_key in var_model_configs): - if(old_key == 'conv_filters'): - feat_ext = 'cnn' - var_model_configs[new_key] = var_model_configs.pop(old_key) - - # remove invalid keys - if("model" in model_config): - for key in list(model_config["model"].keys()): - if(key not in valid_keys): - model_config["model"].pop(key) - - # -------- Var model config - delete invalid keys -------# - for key in list(var_model_configs.keys()): - if(key not in valid_keys): - var_model_configs.pop(key) - - # -------- set model config -------# - policy_kwargs['feature_extraction'] = feat_ext - agent_config['policy_kwargs'] = policy_kwargs - # config.agent_config = agent_config - # config.model_config = model_config - # if bool(var_agent_configs): #variable configs - # config.var_configs["agent"] = var_agent_configs - # if bool(var_model_configs): - # config.var_configs["model"] = var_model_configs - return agent_config, model_config, var_agent_configs, var_model_configs - - -# change model_config to baselines framework/ decide MLP or CNN policy -def model_to_policy_kwargs(env, model_config): - if(isinstance(env.observation_space, gym.spaces.Discrete) or \ - len(env.observation_space.shape) <= 2): - feat_ext = "mlp" - else: - feat_ext = "cnn" - # Move model config(already on baselines framework) to policy_kwargs - policy_kwargs, cnn_config = {}, {} - for key in model_config["model"].keys(): - if(key == "act_fun"): - policy_kwargs[key] = act_fnc_from_name(model_config["model"][key]) - else: - policy_kwargs[key] = model_config["model"][key] - - if("use_lstm" in policy_kwargs.keys()): - # use_lstm does not exist in baselines, here is used to define the policy - use_lstm = policy_kwargs.pop("use_lstm") - else: - use_lstm = False - - if("n_lstm" in policy_kwargs.keys() and not use_lstm): - policy_kwargs.pop("n_lstm") # not valid if not lstm policy - - # Custom Feature extractor - if(feat_ext == "cnn" and ("net_arch" in policy_kwargs)): - cnn_config["act_fun"] = act_fnc_from_name(policy_kwargs.pop("act_fun")) - cnn_config["net_arch"] = policy_kwargs.pop("net_arch") - # Uncomment to pass through custom cnn - policy_kwargs['cnn_extractor'] = vision_net - policy_kwargs["kwargs"] = cnn_config - - if(feat_ext=="mlp" and "net_arch" in policy_kwargs): - policy_kwargs.pop("net_arch") - - policy_kwargs['feature_extraction'] = feat_ext - - return policy_kwargs, use_lstm - - -def act_fnc_from_name(key): - if(key == "tanh"): - return tf.nn.tanh - elif(key == "sigmoid"): - return tf.nn.sigmoid - elif(key == "leakyrelu"): - return tf.nn.leaky_relu - else: #default - return tf.nn.relu - - -def vision_net(scaled_images, kwargs): - if ("act_fun" in kwargs): - activ_fn = kwargs['act_fun'] - else: # default - activ_fn = tf.nn.relu - - output, i = scaled_images, 0 - for i, layer_def in enumerate(kwargs['net_arch'][:-1], start=1): - n_filters, kernel, stride = layer_def - scope = "c%d" % (i) - output = activ_fn(conv(output, - scope, - n_filters=n_filters, - filter_size=kernel[0], - stride=stride, - pad="SAME", - init_scale=np.sqrt(2))) - - # last layer has valid padding - n_filters, kernel, stride = kwargs['net_arch'][-1] - output = activ_fn(conv(output, - scope="c%d" % (i+1), - n_filters=n_filters, - filter_size=kernel[0], - stride=stride, - pad="VALID", - init_scale=np.sqrt(2))) - output = conv_to_fc(output) # No linear layer - # output = activ_fn(linear(output, 'fc1', n_hidden=512, init_scale=np.sqrt(2))) - return output - - -def init_agent(env, config_algorithm, model_cfg, agent_config_baselines): - policy_kwargs, use_lstm = \ - model_to_policy_kwargs(env, model_cfg) - # Change feature extractor depending on environment as in ray - agent_config_baselines["policy_kwargs"] = policy_kwargs - - # Use feed forward policies and - # specify cnn feature extractor in configuration - if config_algorithm == 'DQN': - model = DQN(env=env, - policy=sb.deepq.policies.FeedForwardPolicy, - **agent_config_baselines, - verbose=1) - elif config_algorithm == 'DDPG': - # action noise is none by default meaning it does not explore.. - # condiguration using ray defaults - # https://docs.ray.io/en/latest/rllib-algorithms.html?highlight=ddpg#deep-deterministic-policy-gradients-ddpg-td3 - n_actions = env.action_space.shape[0] - agent_config_baselines["action_noise"] = OrnsteinUhlenbeckActionNoise( - mean=np.zeros(n_actions),\ - sigma=float(0.2) * np.ones(n_actions)) - # ddpg - # can also use as agent parameter - # "normalize_observations = True " - # or "normalize_returns" = True - model = DDPG(env=env, - policy=sb.ddpg.policies.FeedForwardPolicy, - **agent_config_baselines, - verbose=1) - elif config_algorithm == "TD3": - model = TD3(env=env, - policy=sb.td3.policies.FeedForwardPolicy, - **agent_config_baselines, - verbose=1) - elif config_algorithm == "A3C" or config_algorithm == "A2C": - policy = sb.common.policies.LstmPolicy if use_lstm \ - else sb.common.policies.FeedForwardPolicy - model = A2C(env=env, - policy=policy, - **agent_config_baselines, - verbose=1) - else: # 'SAC - model = SAC(env=env, - policy=sb.sac.policies.FeedForwardPolicy, - **agent_config_baselines, - verbose=1) - return model - - -def init_environments(config_algorithm, current_config, env_config, eval_cfg): - env_config = process_env_keys(env_config, - current_config) - env = gym.make(current_config['env'], - **env_config) - - # if time limit, wrap it - if("horizon" in current_config['env']): - train_horizon = current_config['env']["horizon"] - env = TimeLimit(env, max_episode_steps=train_horizon) # horizon - env = sb.bench.Monitor(env, None) # , "../", force=True) - # Automatically normalize the input features and reward - if (config_algorithm == "DDPG" - or config_algorithm == "A2C" - or config_algorithm == "A3C"): - env = DummyVecEnv([lambda: env]) - env = VecNormalize(env, - norm_obs=False, - norm_reward=True, - clip_obs=10.) - - # limit max timesteps in evaluation - eval_horizon = 100 - if("horizon" in eval_cfg): - eval_horizon = eval_cfg["horizon"] - eval_env = gym.make(current_config['env'], - **env_config) - eval_env = TimeLimit(eval_env, max_episode_steps=eval_horizon) - return env, eval_env - - -def process_env_keys(env_config, current_config): - dict_keys = list(env_config.keys()) - for key in dict_keys: - if key == 'reward_noise': - reward_noise_ = current_config["env_config"][key] - env_config[key] = lambda a: a.normal(0, reward_noise_) - env_config['reward_noise_std'] = reward_noise_ - elif key == 'transition_noise' and env_config["state_space_type"] == "continuous": - transition_noise_ = current_config["transition_noise"][key] - env_config[key] = lambda a: a.normal(0, transition_noise_) - env_config['transition_noise_std'] = transition_noise_ - - if("state_space_type" in env_config): - if env_config["state_space_type"] == 'continuous': - env_config["action_space_dim"] = env_config["state_space_dim"] - - return env_config - - -class CustomCallback(sb.common.callbacks.BaseCallback): - """ - Callback for evaluating an agent. - :param eval_env: (Union[gym.Env, VecEnv]) The environment used for initialization - :param n_eval_episodes: (int) The number of episodes to test the agent - :param eval_freq: (int) Evaluate the agent every eval_freq call of the callback. - :param deterministic: (bool) Whether the evaluation should use a stochastic or deterministic actions. - :param verbose: (int) - """ - - def __init__( - self, - eval_env: Union[gym.Env, VecEnv], - n_eval_episodes: int = 5, - eval_interval: int = 1, - timesteps_per_iteration: int = 1000, - deterministic: bool = True, - verbose: int = 1, - file_name: str = "./evaluation.csv", - config_algorithm: str ="", - var_configs=None - ): - super(CustomCallback, self).__init__(verbose=verbose) - self.n_eval_episodes = n_eval_episodes - self.eval_freq = timesteps_per_iteration * eval_interval - self.deterministic = deterministic - self.file_name = file_name - self.timesteps_per_iteration = timesteps_per_iteration - self.training_iteration = 1 - self.total_timesteps = 0 - self.config_algorithm = config_algorithm - self.var_configs = var_configs - self.last_episode_count = 0 - self.episodes_in_iter = 0 - self.best_eval_mean = 0 - # self.best_train_return = 0 - # Convert to VecEnv for consistency - if not isinstance(eval_env, VecEnv): - eval_env = DummyVecEnv([lambda: eval_env]) - eval_env = VecNormalize(eval_env, norm_obs=False, norm_reward=True, clip_obs=10.) - - if isinstance(eval_env, VecEnv): - assert eval_env.num_envs == 1, "You must pass only one environment for evaluation" - - self.eval_env = eval_env - - # evaluate policy when step % eval_freq == 0, return rewards and lengths list of n_eval_episodes elements - def _on_step(self): - # count steps - self.total_timesteps+=1 - # training log - # training iteration done, log train csv - if(self.total_timesteps % self.timesteps_per_iteration == 0): - self.write_train_result() - self.training_iteration += 1 - - # evaluation - if self.eval_freq > 0 and self.n_calls % self.eval_freq == 0: - # Sync training and eval env if there is VecNormalize - sync_envs_normalization(self.training_env, self.eval_env) - - episode_rewards, episode_lengths = sb.common.evaluation.evaluate_policy( - self.model, - self.eval_env, - n_eval_episodes=self.n_eval_episodes, - render=False, - deterministic=self.deterministic, - return_episode_rewards=True, - ) - - # write evaluation csv - self.write_eval_results(episode_rewards, episode_lengths) - - mean_reward, std_reward = np.mean(episode_rewards), np.std(episode_rewards) - mean_ep_length, std_ep_length = np.mean(episode_lengths), np.std(episode_lengths) - - if(self.best_eval_mean < mean_reward): - self.model.save("%s_best_eval" % (self.file_name)) - self.best_eval_mean = mean_reward - - if self.verbose > 0: - print(f"Eval num_timesteps={self.num_timesteps}, " f"episode_reward={mean_reward:.2f} +/- {std_reward:.2f}") - print(f"Episode length: {mean_ep_length:.2f} +/- {std_ep_length:.2f}") - return True - - # def _on_rollout_end(self): - # env = self.training_env - # if isinstance(self.training_env, VecEnv): - # env = env.unwrapped.envs[0] # only using one environment - # episode_rewards = env.get_episode_rewards() - # if(episode_rewards[-1] > self.best_train_return): - # self.model.save("%s_best_train" % (self.file_name)) - # self.best_train_return = episode_rewards[-1] - - # Used in callback after every episode has ended during evaluation - # replaces: def on_episode_end(info) - def write_eval_results(self, episode_rewards, episode_lengths): - eval_filename = self.file_name + '_eval.csv' - fout = open(eval_filename, 'a') # hardcoded - for reward_this_episode, length_this_episode in zip(episode_rewards, episode_lengths): - fout.write(str(reward_this_episode[0]) + ' ' + str(length_this_episode) + "\n") - fout.close() - - # Write training stats to CSV file at end of every training iteration - def write_train_result(self): - env, training_iteration, total_timesteps = self.training_env, self.training_iteration, self.total_timesteps - config_algorithm, var_configs = self.config_algorithm, self.var_configs - - if isinstance(env, VecEnv): - env = env.unwrapped.envs[0] # only using one environment - - # A2C can handle multiple envs.. - # if(self.config_algorithm == "A2C" or self.config_algorithm =="A3C"): - # env = env.envs[0]#take first env - - # Writes every iteration, would slow things down. #hack - fout = open(self.file_name + '.csv', 'a') # hardcoded - fout.write(str(training_iteration) + ' ' + config_algorithm + ' ') - for config_type, config_dict in var_configs.items(): - for key in config_dict: - if config_type == "env": - env_config = env.config - if key == 'reward_noise': - fout.write(str(env_config['reward_noise_std']) + ' ') # hack - elif key == 'transition_noise' and env_config["state_space_type"] == "continuous": - fout.write(str(env_config['transition_noise_std']) + ' ') # hack - else: - fout.write(str(env_config[key]).replace(' ', '') + ' ') - elif config_type == "agent": - fout.write(str(getattr(self.model, key)).replace(' ', '') + ' ') - elif config_type == "model": - if(key == "net_arch"):#this is kwargs as it is sent to visionet - fout.write(str(getattr(self.model, "policy_kwargs")["kwargs"][key]).replace(' ', '') + ' ') - else: - fout.write(str(getattr(self.model, "policy_kwargs")[key]).replace(' ', '') + ' ') - - # Write train statss - episode_rewards = env.get_episode_rewards() - episode_lengths = env.get_episode_lengths() - # update episodes - n_episodes = len(episode_rewards) - self.episodes_in_iter = n_episodes - self.last_episode_count - if(self.episodes_in_iter == 0): # no episodes in iteration - if(n_episodes) == 0: # special case when there are no episodes so far - episode_reward_mean = np.sum(env.rewards) # cummulative reward so far - episode_length_mean = env.get_total_steps() # all steps so far - else: - # iteration end, no episode end - # start = self.timesteps_per_iteration*training_iteration - # episode_reward_mean = np.sum(env.rewards[start:]) - # episode_length_mean = self.timesteps_per_iteration - episode_reward_mean = np.mean(episode_rewards) - episode_length_mean = self.timesteps_per_iteration - else: - # episode stats are from all steps taken in env then we need to take mean over "iterations": - # start , stop = self.last_episode_count, self.last_episode_count + self.episodes_in_iter - 1 - episode_reward_mean = np.mean(episode_rewards[self.last_episode_count:]) - episode_length_mean = np.mean(episode_lengths[self.last_episode_count:]) - self.last_episode_count = n_episodes - - # timesteps_total always HAS to be the 1st written: analysis.py depends on it - fout.write(str(total_timesteps) + ' ' + - str(episode_reward_mean) + - ' ' + str(episode_length_mean) + '\n') - fout.close() - - # We did not manage to find an easy way to log evaluation stats for Ray without the following hack which demarcates the end of a training iteration in the evaluation stats file - hack_filename_eval = self.file_name + '_eval.csv' - fout = open(hack_filename_eval, 'a') #hardcoded - fout.write('#HACK STRING EVAL' + "\n") - fout.close() - - #info["result"]["callback_ok"] = True - return True \ No newline at end of file diff --git a/mdp_playground/config_processor/config_processor.py b/mdp_playground/config_processor/config_processor.py deleted file mode 100644 index aa553bc..0000000 --- a/mdp_playground/config_processor/config_processor.py +++ /dev/null @@ -1,543 +0,0 @@ -from ray.tune.registry import register_env -from .baselines_processor import agent_to_baselines, model_to_policy_kwargs -import copy -import sys, os -import collections - -mujoco_envs = ["HalfCheetahWrapper-v3", "HopperWrapper-v3", "PusherWrapper-v2", "ReacherWrapper-v2"] - -import mdp_playground -from mdp_playground.envs import RLToyEnv -from ray.tune.registry import register_env -register_env("RLToy-v0", lambda config: RLToyEnv(**config)) -register_env("GymEnvWrapper-Atari", lambda config: create_gym_env_wrapper_atari(config)) -register_env("GymEnvWrapperFrameStack-Atari", lambda config: create_gym_env_wrapper_frame_stack_atari(config)) - -from ray.rllib.models.preprocessors import OneHotPreprocessor -from ray.rllib.models import ModelCatalog -ModelCatalog.register_custom_preprocessor("ohe", OneHotPreprocessor) - - -def process_configs(config_file, stats_file_prefix, config_num, log_level, framework='ray'): - config_file_path = os.path.abspath('/'.join(config_file.split('/')[:-1])) - - sys.path.insert(1, config_file_path) # hack - import importlib - config = importlib.import_module(config_file.split('/')[-1], package=None) - print("Number of seeds for environment:", config.num_seeds) - - - # hacks needed to setup Ray callbacks below - var_configs_deepcopy = copy.deepcopy(config.var_configs) # hack because this needs to be read in on_train_result and trying to read config there raises an error because it's been imported from a Python module and I think they try to reload it there. - if "timesteps_total" in dir(config): - hacky_timesteps_total = config.timesteps_total # hack - - config_algorithm = config.algorithm # hack - # sys.exit(0) - - columns_to_write = [] - for config_type, config_dict in var_configs_deepcopy.items(): - for key in config_dict: - columns_to_write.append(key) - - stats_file_name = stats_file_prefix + '.csv' - - init_stats_file(stats_file_name, columns_to_write) - - # Ray specific setup: - if framework.lower() == 'ray': - from ray import tune - setup_ray(config, config_num, log_level) - on_train_result, on_episode_end = setup_ray_callbacks(stats_file_prefix, var_configs_deepcopy, hacky_timesteps_total, config_algorithm) - - # default Define default config which gets overwritten with config in config.py file if present. - default_config = { - "callbacks": { - # "on_episode_start": tune.function(on_episode_start), - # "on_episode_step": tune.function(on_episode_step), - "on_episode_end": tune.function(on_episode_end), - # "on_sample_end": tune.function(on_sample_end), - "on_train_result": tune.function(on_train_result), - # "on_postprocess_traj": tune.function(on_postprocess_traj), - }, - # "log_level": 'WARN', - } - - # Stable Baselines specific setup: - elif framework.lower() == 'stable_baselines': - cfg = (config.algorithm, - config.agent_config, - config.model_config, - config.var_configs) - agent_config, model_config, var_agent_configs, var_model_configs = \ - agent_to_baselines(cfg) - config.agent_config = agent_config - config.model_config = model_config - config.var_agent_configs = var_agent_configs - config.var_model_configs = var_model_configs - var_env_configs = collections.OrderedDict() - if("env" in var_configs_deepcopy): - var_env_configs = var_configs_deepcopy["env"] - var_configs_deepcopy = {"agent": collections.OrderedDict(var_agent_configs), - "model": collections.OrderedDict(var_model_configs), - "env": var_env_configs} - - default_config = {"stats_file_name": stats_file_name, - "var_configs_deepcopy": var_configs_deepcopy} - else: - raise ValueError("Framework passed was not a valid option. It was: " + framework + ". Available options are: ray and stable_baselines.") - - - varying_configs = get_grid_of_configs(config.var_configs) - # print("VARYING_CONFIGS:", varying_configs) - - final_configs = combined_processing(default_config, config.env_config, config.agent_config, config.model_config, config.eval_config, varying_configs=varying_configs, framework=framework, algorithm=config.algorithm) - - return config, final_configs - - -def setup_ray(config, config_num, log_level): - import ray - if config.algorithm == 'DQN': #hack - ray.init(object_store_memory=int(2e9), redis_max_memory=int(1e9), temp_dir='/tmp/ray' + str(config_num), include_webui=False, logging_level=log_level, local_mode=True) #webui_host='0.0.0.0'); logging_level=logging.INFO, #hardcoded - - # ray.init(object_store_memory=int(2e9), redis_max_memory=int(1e9), local_mode=True, plasma_directory='/tmp') #, memory=int(8e9), local_mode=True # local_mode (bool): If true, the code will be executed serially. This is useful for debugging. # when true on_train_result and on_episode_end operate in the same current directory as the script. A3C is crashing in local mode, so didn't use it and had to work around by giving full path + filename in stats_file_name.; also has argument driver_object_store_memory=, plasma_directory='/tmp' - elif config.algorithm == 'A3C': #hack - ray.init(object_store_memory=int(2e9), redis_max_memory=int(1e9), temp_dir='/tmp/ray' + str(config_num), include_webui=False, logging_level=log_level) - # ray.init(object_store_memory=int(2e9), redis_max_memory=int(1e9), local_mode=True, plasma_directory='/tmp') - else: - ray.init(object_store_memory=int(2e9), redis_max_memory=int(1e9), local_mode=True, temp_dir='/tmp/ray' + str(config_num), include_webui=False, logging_level=log_level) - - -def init_stats_file(stats_file_name, columns_to_write): - fout = open(stats_file_name, 'a') #hardcoded - fout.write('# training_iteration, algorithm, ') - for column in columns_to_write: - # if config_type == "agent": - # if config_algorithm == 'SAC' and key == "critic_learning_rate": - # real_key = "lr" #hack due to Ray's weird ConfigSpaces - # fout.write(real_key + ', ') - # elif config_algorithm == 'SAC' and key == "fcnet_hiddens": - # #hack due to Ray's weird ConfigSpaces - # fout.write('fcnet_hiddens' + ', ') - # else: - # fout.write(key + ', ') - # else: - fout.write(column + ', ') - fout.write('timesteps_total, episode_reward_mean, episode_len_mean\n') - fout.close() - -def setup_ray_callbacks(stats_file_prefix, var_configs_deepcopy, hacky_timesteps_total, config_algorithm): - # Setup Ray callbacks - # Ray callback to write training stats to CSV file at end of every training iteration - #hack Didn't know how to move this function to config. It requires the filename which _has_ to be possible to set in run_experiments.py. Had to take care of stats_file_prefix, var_configs_deepcopy, hacky_timesteps_total, config_algorithm; and had to initialise file writing in here (config_processor). - def on_train_result(info): - training_iteration = info["result"]["training_iteration"] - # algorithm = info["trainer"]._name - - # Writes every iteration, would slow things down. #hack - fout = open(stats_file_prefix + '.csv', 'a') #hardcoded - fout.write(str(training_iteration) + ' ' + config_algorithm + ' ') - for config_type, config_dict in var_configs_deepcopy.items(): - for key in config_dict: - if config_type == "env": - field_val = info["result"]["config"]["env_config"][key] - if isinstance(field_val, float): - str_to_write = '%.2e' % field_val - elif type(field_val) == list: - str_to_write = "[" - for elem in field_val: - # print(key) - str_to_write += '%.2e' % elem if isinstance(elem, float) else str(elem) - str_to_write += "," - str_to_write += "]" - else: - str_to_write = str(field_val).replace(' ', '') - str_to_write += ' ' - fout.write(str_to_write) - elif config_type == "agent": - if config_algorithm == 'SAC' and key == "critic_learning_rate": - real_key = "lr" #hack due to Ray's weird ConfigSpaces - fout.write('%.2e' % info["result"]["config"]['optimization'][key].replace(' ', '') + ' ') - elif config_algorithm == 'SAC' and key == "fcnet_hiddens": - #hack due to Ray's weird ConfigSpaces - str_to_write = str(info["result"]["config"]["Q_model"][key]).replace(' ', '') + ' ' - fout.write(str_to_write) - # elif config_algorithm == 'SAC' and key == "policy_model": - # #hack due to Ray's weird ConfigSpaces - # pass - # fout.write(str(info["result"]["config"][key]['fcnet_hiddens']).replace(' ', '') + ' ') - else: - if key == "exploration_fraction" and "exploration_fraction" not in info["result"]["config"]: #hack ray 0.7.3 will have exploration_fraction but not versions later than ~0.9 - field_val = info["result"]["config"]["exploration_config"]["epsilon_timesteps"] / hacky_timesteps_total # convert to fraction to be similar to old exploration_fraction - else: - field_val = info["result"]["config"][key] - str_to_write = '%.2e' % field_val if isinstance(field_val, float) else str(field_val).replace(' ', '') - str_to_write += ' ' - fout.write(str_to_write) - elif config_type == "model": - # if key == 'conv_filters': - fout.write(str(info["result"]["config"]["model"][key]).replace(' ', '') + ' ') - - # Write train stats - timesteps_total = info["result"]["timesteps_total"] # also has episodes_total and training_iteration - episode_reward_mean = info["result"]["episode_reward_mean"] # also has max and min - # print("Custom_metrics: ", info["result"]["step_reward_mean"], info["result"]["step_reward_max"], info["result"]["step_reward_min"]) - episode_len_mean = info["result"]["episode_len_mean"] - - fout.write(str(timesteps_total) + ' ' + '%.2e' % episode_reward_mean + - ' ' + '%.2e' % episode_len_mean + '\n') # timesteps_total always HAS to be the 1st written: analysis.py depends on it - fout.close() - - # print("##### stats_file_name: ", stats_file_name) - # print(os.getcwd()) - - # We did not manage to find an easy way to log evaluation stats for Ray without the following hack which demarcates the end of a training iteration in the evaluation stats file - stats_file_eval = stats_file_prefix + '_eval.csv' - fout = open(stats_file_eval, 'a') #hardcoded - - import os, psutil - mem_used_mb = psutil.Process(os.getpid()).memory_info().rss / 1024 ** 2 - - fout.write('#HACK STRING EVAL, mem_used_mb: ' + str(mem_used_mb) + "\n") - fout.close() - - info["result"]["callback_ok"] = True - - - # Ray callback to write evaluation stats to CSV file at end of every training iteration - # on_episode_end is used because these results won't be available on_train_result - # but only after every episode has ended during evaluation (evaluation phase is - # checked for by using dummy_eval) - def on_episode_end(info): - if "dummy_eval" in info["env"].get_unwrapped()[0].config: - # print("###on_episode_end info", info["env"].get_unwrapped()[0].config["make_denser"], info["episode"].total_reward, info["episode"].length) #, info["episode"]._agent_reward_history) - reward_this_episode = info["episode"].total_reward - length_this_episode = info["episode"].length - stats_file_eval = stats_file_prefix + '_eval.csv' - fout = open(stats_file_eval, 'a') #hardcoded - fout.write('%.2e' % reward_this_episode + ' ' + str(length_this_episode) + "\n") - fout.close() - - def on_episode_step(info): - episode = info["episode"] - if "step_reward" not in episode.custom_metrics: - episode.custom_metrics["step_reward"] = [] - step_reward = episode.total_reward - else: - step_reward = episode.total_reward - np.sum(episode.custom_metrics["step_reward"]) - episode.custom_metrics["step_reward"].append(step_reward) # This line - # should not be executed the 1st time this function is called because - # no step has actually taken place then (Ray 0.9.0)!! - # episode.custom_metrics = {} - # episode.user_data = {} - # episode.hist_data = {} - # Next 2 are the same, except 1st one is total episodic reward _per_ agent - # episode.agent_rewards = defaultdict(float) - # episode.total_reward += reward - # only hack to get per step reward seems to be to store prev total_reward - # and subtract it from that - # episode._agent_reward_history[agent_id].append(reward) - - return on_train_result, on_episode_end - -def get_grid_of_configs(var_configs): - ''' - var_configs: dict of dicts of lists as values - A dict of dicts with lists as the leaf values to allow each configuration option to take multiple possible values. - ''' - value_tuples = [] - - # TODO Currently, the var_configs dict is nested, might want to make it single level. However, the config dicts used in Ray are nested, so keep it like this for now. Further, the 2nd level division chosen for configs currently, i.e., env, agent, model is a bit arbitrary, but better like this since it can be compliant with Ray and other frameworks and additional processing can take place in framework_specific_processing() below. - for config_type, config_dict in var_configs.items(): - for key in config_dict: - assert type(var_configs[config_type][key]) == list, "var_configs should be a dict of dicts with lists as the leaf values to allow each configuration option to take multiple possible values" - value_tuples.append(var_configs[config_type][key]) - - import itertools - if len(value_tuples) == 0: - cartesian_product_configs = [] # Edge case, else it'd become [()]. - else: - cartesian_product_configs = list(itertools.product(*value_tuples)) - - print("Total number of configs. to run:", len(cartesian_product_configs)) - - grid_of_configs = [] - - for enum_conf_1, current_config in enumerate(cartesian_product_configs): - env_config = {"env": {}} - model_config = {"model": {}} - agent_config = {"agent": {}} - - for config_type, config_dict in var_configs.items(): - for key in config_dict: - # if config_type == "env_config": # There is a dummy seed in the env_config because it's not used in the environment. It implies a different seed for the agent on every launch as the seed for Ray is not being set here. I faced problems with Ray's seeding process. - if config_type == "env": - env_config["env"][key] = current_config[list(var_configs["env"]).index(key)] - - elif config_type == "agent": #hack All these are hacks to get around different limitations - num_configs_done = len(list(var_configs["env"])) - agent_config["agent"][key] = current_config[num_configs_done + list(var_configs[config_type]).index(key)] - - elif config_type == "model": - num_configs_done = len(list(var_configs["env"])) + len(list(var_agent_configs)) - model_config["model"][key] = current_config[num_configs_done + list(var_configs[config_type]).index(key)] - - combined_config = {**agent_config, **model_config, **env_config} - - grid_of_configs.append(combined_config) - - return grid_of_configs - - -def combined_processing(*static_configs, varying_configs, framework='ray', algorithm): - ''' - varying_configs is a dict of dicts with structure: { - } - ''' - # print(len(configs)) - # print(type(configs)) - # print(type(*configs)) - - # Pre-processing common to frameworks: - for i, varying_config in enumerate(varying_configs): - - ###IMP This needs to be done before merging because otherwise varying_config["env"] clashes with - varying_config = {"env_config": varying_config["env"], **varying_config["agent"], "model": varying_config["model"]} - varying_configs[i] = varying_config - - - # Ray specific pre-processing - if framework.lower() == 'ray': - ... - - - # Stable Baselines specific pre-processing - elif framework.lower() == 'stable_baselines': - default, env_cfg, agent_cfg, model_cfg, eval_cfg = static_configs - static_configs = (default, env_cfg, - {"agent": agent_cfg}, - {"model": model_cfg}, - {"evaluation": eval_cfg}) - for i, cfg_dict in enumerate(varying_configs): - var_cfg = cfg_dict.copy() - var_env_cfg = var_cfg.pop('env_config') - var_model_configs = var_cfg.pop('model') - varying_configs[i] = {} - varying_configs[i]["env_config"] = var_env_cfg - varying_configs[i]["model"] = var_model_configs - varying_configs[i]["agent"] = var_cfg - else: - raise ValueError("Framework passed was not a valid option. It was: " + framework + ". Available options are: ray and stable_baselines.") - - - # Merge all configs into one - final_configs = [] - for i in range(len(varying_configs)): - # for in range(len()): - static_configs_copy = copy.deepcopy(static_configs) - merged_conf = deepmerge_multiple_dicts(*static_configs_copy, varying_configs[i]) - final_configs.append(merged_conf) # varying_configs, env_config, agent_config, eval_config - - - # Post-processing common to frameworks: - for i, final_config in enumerate(final_configs): - if final_configs[i]["env"] in mujoco_envs: - if "time_unit" in final_configs[i]["env_config"]: #hack This is needed so that the environment runs the same amount of seconds of simulation, even though episode steps are different. - final_configs[i]["horizon"] /= final_configs[i]["env_config"]["time_unit"] - final_configs[i]["horizon"] = int(final_configs[i]["horizon"]) - - final_configs[i]["learning_starts"] /= final_configs[i]["env_config"]["time_unit"] - final_configs[i]["learning_starts"] = int(final_configs[i]["learning_starts"]) - - final_configs[i]["timesteps_per_iteration"] /= final_configs[i]["env_config"]["time_unit"] - final_configs[i]["timesteps_per_iteration"] = int(final_configs[i]["timesteps_per_iteration"]) - - final_configs[i]["evaluation_config"]["horizon"] /= final_configs[i]["env_config"]["time_unit"] - final_configs[i]["evaluation_config"]["horizon"] = int(final_configs[i]["evaluation_config"]["horizon"]) - - final_configs[i]["train_batch_size"] *= final_configs[i]["env_config"]["time_unit"] # this is needed because Ray (until version 0.8.6 I think) fixes the ratio of number of samples trained/number of steps sampled in environment - final_configs[i]["train_batch_size"] = int(final_configs[i]["train_batch_size"]) - - # hack Common #mujoco wrapper to allow Mujoco envs to be wrapped by MujocoEnvWrapper (which fiddles with lower-level Mujoco stuff) and then by GymEnvWrapper which is more general and basically adds dimensions from MDPP which are common to discrete and continuous environments - # if final_configs[i]["env"] in mujoco_envs: - - # default settings for #timesteps_total - if final_configs[i]["env"] in ["HalfCheetahWrapper-v3"]: #hack - timesteps_total = 3000000 - - from mdp_playground.envs.mujoco_env_wrapper import get_mujoco_wrapper #hack - from gym.envs.mujoco.half_cheetah_v3 import HalfCheetahEnv - wrapped_mujoco_env = get_mujoco_wrapper(HalfCheetahEnv) - register_env("HalfCheetahWrapper-v3", lambda config: create_gym_env_wrapper_mujoco_wrapper(config, wrapped_mujoco_env)) - - elif final_configs[i]["env"] in ["HopperWrapper-v3"]: #hack - timesteps_total = 1000000 - - from mdp_playground.envs.mujoco_env_wrapper import get_mujoco_wrapper #hack - from gym.envs.mujoco.hopper_v3 import HopperEnv - wrapped_mujoco_env = get_mujoco_wrapper(HopperEnv) - register_env("HopperWrapper-v3", lambda config: create_gym_env_wrapper_mujoco_wrapper(config, wrapped_mujoco_env)) - - elif final_configs[i]["env"] in ["PusherWrapper-v2"]: #hack - timesteps_total = 500000 - - from mdp_playground.envs.mujoco_env_wrapper import get_mujoco_wrapper #hack - from gym.envs.mujoco.pusher import PusherEnv - wrapped_mujoco_env = get_mujoco_wrapper(PusherEnv) - register_env("PusherWrapper-v2", lambda config: create_gym_env_wrapper_mujoco_wrapper(config, wrapped_mujoco_env)) - - elif final_configs[i]["env"] in ["ReacherWrapper-v2"]: #hack - timesteps_total = 500000 - - from mdp_playground.envs.mujoco_env_wrapper import get_mujoco_wrapper #hack - from gym.envs.mujoco.reacher import ReacherEnv - wrapped_mujoco_env = get_mujoco_wrapper(ReacherEnv) - register_env("ReacherWrapper-v2", lambda config: create_gym_env_wrapper_mujoco_wrapper(config, wrapped_mujoco_env)) - - elif final_configs[i]["env"] in ["GymEnvWrapper-Atari"]: #hack - if "AtariEnv" in final_configs[i]["env_config"]: - timesteps_total = 10_000_000 - - else: - if algorithm == 'DQN': - timesteps_total = 20000 - elif algorithm == 'A3C': # hack - timesteps_total = 150000 - else: # if algorithm == 'DDPG': #hack - timesteps_total = 20000 - - if final_configs[i]["env"] in mujoco_envs: - if "time_unit" in final_configs[i]["env_config"]: #hack This is needed so that the environment runs the same amount of seconds of simulation, even though episode steps are different. - timesteps_total /= final_configs[i]["env_config"]["time_unit"] - timesteps_total = int(timesteps_total) - - - final_configs[i]["timesteps_total"] = timesteps_total - - # Post-processing for Ray: - if framework.lower() == 'ray': - for i in range(len(final_configs)): - # for config_type in varying_config: - for key in final_configs[i]: - value = final_configs[i][key] - - if algorithm == 'SAC': - if key == 'critic_learning_rate': # hack - final_configs[i]['optimization'] = { - key: value, - 'actor_learning_rate': value, - 'entropy_learning_rate': value, - } - if key == 'fcnet_hiddens': # hack - final_configs[i]['Q_model'] = { - key: value, - "fcnet_activation": "relu", - } - final_configs[i]['policy_model'] = { - key: value, - "fcnet_activation": "relu", - } - - if algorithm == 'DDPG': ###TODO Find a better way to enforce these?? Especially problematic for TD3 because then more values for target_noise_clip are witten to CSVs than actually used during HPO but for normal (non-HPO) runs this needs to be not done. - if key == "critic_lr": - final_configs[i]["actor_lr"] = value - if key == "critic_hiddens": - final_configs[i]["actor_hiddens"] = value - if algorithm == 'TD3': - if key == "target_noise_clip_relative": - final_configs[i]["target_noise_clip"] = final_configs[i]["target_noise_clip_relative"] * final_configs[i]["target_noise"] - del final_configs[i]["target_noise_clip_relative"] #hack have to delete it otherwise Ray will crash for unknown config param. - - elif key == "model": - for key_2 in final_configs[i][key]: - if key_2 == "use_lstm": - final_configs[i][key]["max_seq_len"] = final_configs[i]["env_config"]["delay"] + final_configs[i]["env_config"]["sequence_length"] + 1 - - - # Post-processing for Stable Baselines: - elif framework.lower() == 'stable_baselines': - ts_k = "timesteps_per_iteration" - for i, config in enumerate(final_configs): - model_config = config["model"] - use_lstm = False - if("use_lstm" in model_config["model"]): - use_lstm = model_config["model"]["use_lstm"] - if(ts_k in config["agent"]): - # this is not part of baselines parameters, need to separate - timesteps_per_iteration = config["agent"].pop(ts_k) - config[ts_k] = timesteps_per_iteration - else: - config[ts_k] = 1000 # default - config["use_lstm"] = use_lstm - - return final_configs - - -def create_gym_env_wrapper_mujoco_wrapper(config, wrapped_mujoco_env): - '''Creates a GymEnvWrapper around a MujocoEnvWrapper - ''' - from mdp_playground.envs.gym_env_wrapper import GymEnvWrapper - me = wrapped_mujoco_env(**config) - gew = GymEnvWrapper(me, **config) ##IMP Had initially thought to put this config in config["GymEnvWrapper"] but because of code below which converts var_env_configs to env_config, it's best to leave those configs as top level configs in the dict! - return gew - - -def deepmerge_multiple_dicts(*configs): - ''' - ''' - merged_configs = {} - for i in range(len(configs)): - # print(i) - merged_configs = deepmerge(merged_configs, configs[i]) - - return merged_configs - - -from functools import reduce -def deepmerge(a, b, path=None, overwrite=True): - '''Merges dict b into dict a - overwrite : bool - Overwrites value in a with value in b if True with a warning, else raises Exception - Based on: https://stackoverflow.com/questions/7204805/how-to-merge-dictionaries-of-dictionaries/7205107#7205107 - ''' - if path is None: path = [] - for key in b: - if key in a: - if isinstance(a[key], dict) and isinstance(b[key], dict): - deepmerge(a[key], b[key], path + [str(key)]) - elif a[key] == b[key]: - pass # same leaf value - else: - if overwrite: - a[key] = b[key] - warnings.warn("Overwrote value " + str(a[key]) + " with " + str(b[key]) + " while merging dicts.") - else: - raise Exception('Conflict at %s' % '.'.join(path + [str(key)])) - else: - a[key] = b[key] - return a - - - -def create_gym_env_wrapper_atari(config): - from gym.envs.atari import AtariEnv - from mdp_playground.envs.gym_env_wrapper import GymEnvWrapper - ae = AtariEnv(**config["AtariEnv"]) - gew = GymEnvWrapper(ae, **config) ##IMP Had initially thought to put this config in config["GymEnvWrapper"] but because of code below which converts var_env_configs to env_config, it's best to leave those configs as top level configs in the dict! - return gew - - -def create_gym_env_wrapper_frame_stack_atari(config): #hack ###TODO remove? - '''When using frameStack GymEnvWrapper should wrap AtariEnv using wrap_deepmind_ray and therefore this function sets "wrap_deepmind_ray": True and 'frame_skip': 1 inside config so as to keep config same as for create_gym_env_wrapper_atari above and reduce manual errors when switching between the 2. - ''' - config["wrap_deepmind_ray"] = True #hack - config["frame_skip"] = 1 #hack - from gym.envs.atari import AtariEnv - from mdp_playground.envs.gym_env_wrapper import GymEnvWrapper - import gym - game = config["AtariEnv"]["game"] - game = ''.join([g.capitalize() for g in game.split('_')]) - ae = gym.make('{}NoFrameskip-v4'.format(game)) - gew = GymEnvWrapper(ae, **config) ##IMP Had initially thought to put this config in config["GymEnvWrapper"] but because of code below which converts var_env_configs to env_config, it's best to leave those configs as top level configs in the dict! - return gew \ No newline at end of file diff --git a/plot_experiments.ipynb b/plot_experiments.ipynb index 0d17c91..cbee666 100644 --- a/plot_experiments.ipynb +++ b/plot_experiments.ipynb @@ -422,4179 +422,63 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ + "dir_name /home/rajanr/mdpp_12744267_SAC_target_radius_can_use_as_sample\n", + "Writing BOHB to cave output to /home/rajanr/mdpp_to_cave\n", "\u001b[1;31mLoading data from a sequential run/already combined runs of experiment configurations.\u001b[0;0m\n", - "../mdpp_to_cave/a3c_seq\n" - ] - }, - { - "data": { - "text/html": [ - "\n", - "\n", - "
\n", - "
\n", - "
\n", - " \n", - "
\n", - "
\n", - "
\n", - "
\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
DefaultIncumbent
Quality-26.43-42.26
\n", - "
\n", - "
\n", - "
\n", - " \n", - "
" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/pimp/evaluator/local_parameter_importance.py:268: RuntimeWarning: invalid value encountered in double_scalars\n", - " overall_var_per_tree = {p : [t / sum_var_per_tree[idx] for idx, t in enumerate(trees)] for p, trees in\n", - "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/pimp/evaluator/local_parameter_importance.py:402: UserWarning: Attempted to set non-positive top ylim on a log-scaled axis.\n", - "Invalid limit will be ignored.\n", - " ax1.set_ylim([min_y * 0.95, max_y])\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute('style', 'box-sizing: content-box;');\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " var nentries = entries.length;\n", - " for (var i = 0; i < nentries; i++) {\n", - " var entry = entries[i];\n", - " var width, height;\n", - " if (entry.contentBoxSize) {\n", - " if (entry.contentBoxSize instanceof Array) {\n", - " // Chrome 84 implements new version of spec.\n", - " width = entry.contentBoxSize[0].inlineSize;\n", - " height = entry.contentBoxSize[0].blockSize;\n", - " } else {\n", - " // Firefox implements old version of spec.\n", - " width = entry.contentBoxSize.inlineSize;\n", - " height = entry.contentBoxSize.blockSize;\n", - " }\n", - " } else {\n", - " // Chrome <84 implements even older version of spec.\n", - " width = entry.contentRect.width;\n", - " height = entry.contentRect.height;\n", - " }\n", - "\n", - " // Keep the size of the canvas and rubber band canvas in sync with\n", - " // the canvas container.\n", - " if (entry.devicePixelContentBoxSize) {\n", - " // Chrome 84 implements new version of spec.\n", - " canvas.setAttribute(\n", - " 'width',\n", - " entry.devicePixelContentBoxSize[0].inlineSize\n", - " );\n", - " canvas.setAttribute(\n", - " 'height',\n", - " entry.devicePixelContentBoxSize[0].blockSize\n", - " );\n", - " } else {\n", - " canvas.setAttribute('width', width * fig.ratio);\n", - " canvas.setAttribute('height', height * fig.ratio);\n", - " }\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'width: ' + width + 'px; height: ' + height + 'px;'\n", - " );\n", - "\n", - " rubberband_canvas.setAttribute('width', width);\n", - " rubberband_canvas.setAttribute('height', height);\n", - "\n", - " // And update the size in Python. We ignore the initial 0/0 size\n", - " // that occurs as the element is placed into the DOM, which should\n", - " // otherwise not happen due to the minimum size styling.\n", - " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " rubberband_canvas.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " var cursor = msg['cursor'];\n", - " switch (cursor) {\n", - " case 0:\n", - " cursor = 'pointer';\n", - " break;\n", - " case 1:\n", - " cursor = 'default';\n", - " break;\n", - " case 2:\n", - " cursor = 'crosshair';\n", - " break;\n", - " case 3:\n", - " cursor = 'move';\n", - " break;\n", - " }\n", - " fig.rubberband_canvas.style.cursor = cursor;\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " evt.data.type = 'image/png';\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " evt.data\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", - "mpl.findpos = function (e) {\n", - " //this section is from http://www.quirksmode.org/js/events_properties.html\n", - " var targ;\n", - " if (!e) {\n", - " e = window.event;\n", - " }\n", - " if (e.target) {\n", - " targ = e.target;\n", - " } else if (e.srcElement) {\n", - " targ = e.srcElement;\n", - " }\n", - " if (targ.nodeType === 3) {\n", - " // defeat Safari bug\n", - " targ = targ.parentNode;\n", - " }\n", - "\n", - " // pageX,Y are the mouse positions relative to the document\n", - " var boundingRect = targ.getBoundingClientRect();\n", - " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n", - " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n", - "\n", - " return { x: x, y: y };\n", - "};\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * http://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " var canvas_pos = mpl.findpos(event);\n", - "\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " var x = canvas_pos.x * this.ratio;\n", - " var y = canvas_pos.y * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We want\n", - " * to control all of the cursor setting manually through the\n", - " * 'cursor' event from matplotlib */\n", - " event.preventDefault();\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.which === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.which;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.which !== 17) {\n", - " value += 'ctrl+';\n", - " }\n", - " if (event.altKey && event.which !== 18) {\n", - " value += 'alt+';\n", - " }\n", - " if (event.shiftKey && event.which !== 16) {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k';\n", - " value += event.which.toString();\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(msg['content']['data']);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " var manager = IPython.notebook.keyboard_manager;\n", - " if (!manager) {\n", - " manager = IPython.keyboard_manager;\n", - " }\n", - "\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[1;31mLoading data from a sequential run/already combined runs of experiment configurations.\u001b[0;0m\n", - "../mdpp_to_cave/a3c_lstm_seq\n" - ] - }, - { - "data": { - "text/html": [ - "\n", - "\n", - "
\n", - "
\n", - "
\n", - " \n", - "
\n", - "
\n", - "
\n", - "
\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
DefaultIncumbent
Quality-37.31-40.595
\n", - "
\n", - "
\n", - "
\n", - " \n", - "
" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/pimp/evaluator/local_parameter_importance.py:268: RuntimeWarning: invalid value encountered in double_scalars\n", - " overall_var_per_tree = {p : [t / sum_var_per_tree[idx] for idx, t in enumerate(trees)] for p, trees in\n", - "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/pimp/evaluator/local_parameter_importance.py:402: UserWarning: Attempted to set non-positive top ylim on a log-scaled axis.\n", - "Invalid limit will be ignored.\n", - " ax1.set_ylim([min_y * 0.95, max_y])\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute('style', 'box-sizing: content-box;');\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " var nentries = entries.length;\n", - " for (var i = 0; i < nentries; i++) {\n", - " var entry = entries[i];\n", - " var width, height;\n", - " if (entry.contentBoxSize) {\n", - " if (entry.contentBoxSize instanceof Array) {\n", - " // Chrome 84 implements new version of spec.\n", - " width = entry.contentBoxSize[0].inlineSize;\n", - " height = entry.contentBoxSize[0].blockSize;\n", - " } else {\n", - " // Firefox implements old version of spec.\n", - " width = entry.contentBoxSize.inlineSize;\n", - " height = entry.contentBoxSize.blockSize;\n", - " }\n", - " } else {\n", - " // Chrome <84 implements even older version of spec.\n", - " width = entry.contentRect.width;\n", - " height = entry.contentRect.height;\n", - " }\n", - "\n", - " // Keep the size of the canvas and rubber band canvas in sync with\n", - " // the canvas container.\n", - " if (entry.devicePixelContentBoxSize) {\n", - " // Chrome 84 implements new version of spec.\n", - " canvas.setAttribute(\n", - " 'width',\n", - " entry.devicePixelContentBoxSize[0].inlineSize\n", - " );\n", - " canvas.setAttribute(\n", - " 'height',\n", - " entry.devicePixelContentBoxSize[0].blockSize\n", - " );\n", - " } else {\n", - " canvas.setAttribute('width', width * fig.ratio);\n", - " canvas.setAttribute('height', height * fig.ratio);\n", - " }\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'width: ' + width + 'px; height: ' + height + 'px;'\n", - " );\n", - "\n", - " rubberband_canvas.setAttribute('width', width);\n", - " rubberband_canvas.setAttribute('height', height);\n", - "\n", - " // And update the size in Python. We ignore the initial 0/0 size\n", - " // that occurs as the element is placed into the DOM, which should\n", - " // otherwise not happen due to the minimum size styling.\n", - " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " rubberband_canvas.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " var cursor = msg['cursor'];\n", - " switch (cursor) {\n", - " case 0:\n", - " cursor = 'pointer';\n", - " break;\n", - " case 1:\n", - " cursor = 'default';\n", - " break;\n", - " case 2:\n", - " cursor = 'crosshair';\n", - " break;\n", - " case 3:\n", - " cursor = 'move';\n", - " break;\n", - " }\n", - " fig.rubberband_canvas.style.cursor = cursor;\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " evt.data.type = 'image/png';\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " evt.data\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", - "mpl.findpos = function (e) {\n", - " //this section is from http://www.quirksmode.org/js/events_properties.html\n", - " var targ;\n", - " if (!e) {\n", - " e = window.event;\n", - " }\n", - " if (e.target) {\n", - " targ = e.target;\n", - " } else if (e.srcElement) {\n", - " targ = e.srcElement;\n", - " }\n", - " if (targ.nodeType === 3) {\n", - " // defeat Safari bug\n", - " targ = targ.parentNode;\n", - " }\n", - "\n", - " // pageX,Y are the mouse positions relative to the document\n", - " var boundingRect = targ.getBoundingClientRect();\n", - " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n", - " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n", - "\n", - " return { x: x, y: y };\n", - "};\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * http://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " var canvas_pos = mpl.findpos(event);\n", - "\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " var x = canvas_pos.x * this.ratio;\n", - " var y = canvas_pos.y * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We want\n", - " * to control all of the cursor setting manually through the\n", - " * 'cursor' event from matplotlib */\n", - " event.preventDefault();\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.which === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.which;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.which !== 17) {\n", - " value += 'ctrl+';\n", - " }\n", - " if (event.altKey && event.which !== 18) {\n", - " value += 'alt+';\n", - " }\n", - " if (event.shiftKey && event.which !== 16) {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k';\n", - " value += event.which.toString();\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(msg['content']['data']);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " var manager = IPython.notebook.keyboard_manager;\n", - " if (!manager) {\n", - " manager = IPython.keyboard_manager;\n", - " }\n", - "\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[1;31mLoading data from a sequential run/already combined runs of experiment configurations.\u001b[0;0m\n", - "../mdpp_to_cave/a3c_del\n" + "/home/rajanr/mdpp_to_cave/sac_move_to_a_point_target_radius\n" ] - }, - { - "data": { - "text/html": [ - "\n", - "\n", - "
\n", - "
\n", - "
\n", - " \n", - "
\n", - "
\n", - "
\n", - "
\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
DefaultIncumbent
Quality-23.71-41.32
\n", - "
\n", - "
\n", - "
\n", - " \n", - "
" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/pimp/evaluator/local_parameter_importance.py:268: RuntimeWarning: invalid value encountered in double_scalars\n", - " overall_var_per_tree = {p : [t / sum_var_per_tree[idx] for idx, t in enumerate(trees)] for p, trees in\n", - "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/pimp/evaluator/local_parameter_importance.py:402: UserWarning: Attempted to set non-positive top ylim on a log-scaled axis.\n", - "Invalid limit will be ignored.\n", - " ax1.set_ylim([min_y * 0.95, max_y])\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute('style', 'box-sizing: content-box;');\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " var nentries = entries.length;\n", - " for (var i = 0; i < nentries; i++) {\n", - " var entry = entries[i];\n", - " var width, height;\n", - " if (entry.contentBoxSize) {\n", - " if (entry.contentBoxSize instanceof Array) {\n", - " // Chrome 84 implements new version of spec.\n", - " width = entry.contentBoxSize[0].inlineSize;\n", - " height = entry.contentBoxSize[0].blockSize;\n", - " } else {\n", - " // Firefox implements old version of spec.\n", - " width = entry.contentBoxSize.inlineSize;\n", - " height = entry.contentBoxSize.blockSize;\n", - " }\n", - " } else {\n", - " // Chrome <84 implements even older version of spec.\n", - " width = entry.contentRect.width;\n", - " height = entry.contentRect.height;\n", - " }\n", - "\n", - " // Keep the size of the canvas and rubber band canvas in sync with\n", - " // the canvas container.\n", - " if (entry.devicePixelContentBoxSize) {\n", - " // Chrome 84 implements new version of spec.\n", - " canvas.setAttribute(\n", - " 'width',\n", - " entry.devicePixelContentBoxSize[0].inlineSize\n", - " );\n", - " canvas.setAttribute(\n", - " 'height',\n", - " entry.devicePixelContentBoxSize[0].blockSize\n", - " );\n", - " } else {\n", - " canvas.setAttribute('width', width * fig.ratio);\n", - " canvas.setAttribute('height', height * fig.ratio);\n", - " }\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'width: ' + width + 'px; height: ' + height + 'px;'\n", - " );\n", - "\n", - " rubberband_canvas.setAttribute('width', width);\n", - " rubberband_canvas.setAttribute('height', height);\n", - "\n", - " // And update the size in Python. We ignore the initial 0/0 size\n", - " // that occurs as the element is placed into the DOM, which should\n", - " // otherwise not happen due to the minimum size styling.\n", - " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " rubberband_canvas.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " var cursor = msg['cursor'];\n", - " switch (cursor) {\n", - " case 0:\n", - " cursor = 'pointer';\n", - " break;\n", - " case 1:\n", - " cursor = 'default';\n", - " break;\n", - " case 2:\n", - " cursor = 'crosshair';\n", - " break;\n", - " case 3:\n", - " cursor = 'move';\n", - " break;\n", - " }\n", - " fig.rubberband_canvas.style.cursor = cursor;\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " evt.data.type = 'image/png';\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " evt.data\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", - "mpl.findpos = function (e) {\n", - " //this section is from http://www.quirksmode.org/js/events_properties.html\n", - " var targ;\n", - " if (!e) {\n", - " e = window.event;\n", - " }\n", - " if (e.target) {\n", - " targ = e.target;\n", - " } else if (e.srcElement) {\n", - " targ = e.srcElement;\n", - " }\n", - " if (targ.nodeType === 3) {\n", - " // defeat Safari bug\n", - " targ = targ.parentNode;\n", - " }\n", - "\n", - " // pageX,Y are the mouse positions relative to the document\n", - " var boundingRect = targ.getBoundingClientRect();\n", - " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n", - " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n", - "\n", - " return { x: x, y: y };\n", - "};\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * http://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " var canvas_pos = mpl.findpos(event);\n", - "\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " var x = canvas_pos.x * this.ratio;\n", - " var y = canvas_pos.y * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We want\n", - " * to control all of the cursor setting manually through the\n", - " * 'cursor' event from matplotlib */\n", - " event.preventDefault();\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.which === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.which;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.which !== 17) {\n", - " value += 'ctrl+';\n", - " }\n", - " if (event.altKey && event.which !== 18) {\n", - " value += 'alt+';\n", - " }\n", - " if (event.shiftKey && event.which !== 16) {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k';\n", - " value += event.which.toString();\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(msg['content']['data']);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " var manager = IPython.notebook.keyboard_manager;\n", - " if (!manager) {\n", - " manager = IPython.keyboard_manager;\n", - " }\n", - "\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[1;31mLoading data from a sequential run/already combined runs of experiment configurations.\u001b[0;0m\n", - "../mdpp_to_cave/a3c_lstm_del\n" - ] - }, - { - "data": { - "text/html": [ - "\n", - "\n", - "
\n", - "
\n", - "
\n", - " \n", - "
\n", - "
\n", - "
\n", - "
\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
DefaultIncumbent
Quality-36.974-40.209
\n", - "
\n", - "
\n", - "
\n", - " \n", - "
" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/pimp/evaluator/local_parameter_importance.py:268: RuntimeWarning: invalid value encountered in double_scalars\n", - " overall_var_per_tree = {p : [t / sum_var_per_tree[idx] for idx, t in enumerate(trees)] for p, trees in\n", - "/home/jessica/anaconda3/envs/py36_toy_rl/lib/python3.6/site-packages/pimp/evaluator/local_parameter_importance.py:402: UserWarning: Attempted to set non-positive top ylim on a log-scaled axis.\n", - "Invalid limit will be ignored.\n", - " ax1.set_ylim([min_y * 0.95, max_y])\n" - ] - }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "/* global mpl */\n", - "window.mpl = {};\n", - "\n", - "mpl.get_websocket_type = function () {\n", - " if (typeof WebSocket !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof MozWebSocket !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert(\n", - " 'Your browser does not have WebSocket support. ' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.'\n", - " );\n", - " }\n", - "};\n", - "\n", - "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = this.ws.binaryType !== undefined;\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById('mpl-warnings');\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent =\n", - " 'This browser does not support binary websocket messages. ' +\n", - " 'Performance may be slow.';\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = document.createElement('div');\n", - " this.root.setAttribute('style', 'display: inline-block');\n", - " this._root_extra_style(this.root);\n", - "\n", - " parent_element.appendChild(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message('supports_binary', { value: fig.supports_binary });\n", - " fig.send_message('send_image_mode', {});\n", - " if (fig.ratio !== 1) {\n", - " fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n", - " }\n", - " fig.send_message('refresh', {});\n", - " };\n", - "\n", - " this.imageObj.onload = function () {\n", - " if (fig.image_mode === 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function () {\n", - " fig.ws.close();\n", - " };\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "};\n", - "\n", - "mpl.figure.prototype._init_header = function () {\n", - " var titlebar = document.createElement('div');\n", - " titlebar.classList =\n", - " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", - " var titletext = document.createElement('div');\n", - " titletext.classList = 'ui-dialog-title';\n", - " titletext.setAttribute(\n", - " 'style',\n", - " 'width: 100%; text-align: center; padding: 3px;'\n", - " );\n", - " titlebar.appendChild(titletext);\n", - " this.root.appendChild(titlebar);\n", - " this.header = titletext;\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", - "\n", - "mpl.figure.prototype._init_canvas = function () {\n", - " var fig = this;\n", - "\n", - " var canvas_div = (this.canvas_div = document.createElement('div'));\n", - " canvas_div.setAttribute(\n", - " 'style',\n", - " 'border: 1px solid #ddd;' +\n", - " 'box-sizing: content-box;' +\n", - " 'clear: both;' +\n", - " 'min-height: 1px;' +\n", - " 'min-width: 1px;' +\n", - " 'outline: 0;' +\n", - " 'overflow: hidden;' +\n", - " 'position: relative;' +\n", - " 'resize: both;'\n", - " );\n", - "\n", - " function on_keyboard_event_closure(name) {\n", - " return function (event) {\n", - " return fig.key_event(event, name);\n", - " };\n", - " }\n", - "\n", - " canvas_div.addEventListener(\n", - " 'keydown',\n", - " on_keyboard_event_closure('key_press')\n", - " );\n", - " canvas_div.addEventListener(\n", - " 'keyup',\n", - " on_keyboard_event_closure('key_release')\n", - " );\n", - "\n", - " this._canvas_extra_style(canvas_div);\n", - " this.root.appendChild(canvas_div);\n", - "\n", - " var canvas = (this.canvas = document.createElement('canvas'));\n", - " canvas.classList.add('mpl-canvas');\n", - " canvas.setAttribute('style', 'box-sizing: content-box;');\n", - "\n", - " this.context = canvas.getContext('2d');\n", - "\n", - " var backingStore =\n", - " this.context.backingStorePixelRatio ||\n", - " this.context.webkitBackingStorePixelRatio ||\n", - " this.context.mozBackingStorePixelRatio ||\n", - " this.context.msBackingStorePixelRatio ||\n", - " this.context.oBackingStorePixelRatio ||\n", - " this.context.backingStorePixelRatio ||\n", - " 1;\n", - "\n", - " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", - " 'canvas'\n", - " ));\n", - " rubberband_canvas.setAttribute(\n", - " 'style',\n", - " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n", - " );\n", - "\n", - " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", - " if (this.ResizeObserver === undefined) {\n", - " if (window.ResizeObserver !== undefined) {\n", - " this.ResizeObserver = window.ResizeObserver;\n", - " } else {\n", - " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", - " this.ResizeObserver = obs.ResizeObserver;\n", - " }\n", - " }\n", - "\n", - " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", - " var nentries = entries.length;\n", - " for (var i = 0; i < nentries; i++) {\n", - " var entry = entries[i];\n", - " var width, height;\n", - " if (entry.contentBoxSize) {\n", - " if (entry.contentBoxSize instanceof Array) {\n", - " // Chrome 84 implements new version of spec.\n", - " width = entry.contentBoxSize[0].inlineSize;\n", - " height = entry.contentBoxSize[0].blockSize;\n", - " } else {\n", - " // Firefox implements old version of spec.\n", - " width = entry.contentBoxSize.inlineSize;\n", - " height = entry.contentBoxSize.blockSize;\n", - " }\n", - " } else {\n", - " // Chrome <84 implements even older version of spec.\n", - " width = entry.contentRect.width;\n", - " height = entry.contentRect.height;\n", - " }\n", - "\n", - " // Keep the size of the canvas and rubber band canvas in sync with\n", - " // the canvas container.\n", - " if (entry.devicePixelContentBoxSize) {\n", - " // Chrome 84 implements new version of spec.\n", - " canvas.setAttribute(\n", - " 'width',\n", - " entry.devicePixelContentBoxSize[0].inlineSize\n", - " );\n", - " canvas.setAttribute(\n", - " 'height',\n", - " entry.devicePixelContentBoxSize[0].blockSize\n", - " );\n", - " } else {\n", - " canvas.setAttribute('width', width * fig.ratio);\n", - " canvas.setAttribute('height', height * fig.ratio);\n", - " }\n", - " canvas.setAttribute(\n", - " 'style',\n", - " 'width: ' + width + 'px; height: ' + height + 'px;'\n", - " );\n", - "\n", - " rubberband_canvas.setAttribute('width', width);\n", - " rubberband_canvas.setAttribute('height', height);\n", - "\n", - " // And update the size in Python. We ignore the initial 0/0 size\n", - " // that occurs as the element is placed into the DOM, which should\n", - " // otherwise not happen due to the minimum size styling.\n", - " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", - " fig.request_resize(width, height);\n", - " }\n", - " }\n", - " });\n", - " this.resizeObserverInstance.observe(canvas_div);\n", - "\n", - " function on_mouse_event_closure(name) {\n", - " return function (event) {\n", - " return fig.mouse_event(event, name);\n", - " };\n", - " }\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mousedown',\n", - " on_mouse_event_closure('button_press')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseup',\n", - " on_mouse_event_closure('button_release')\n", - " );\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " rubberband_canvas.addEventListener(\n", - " 'mousemove',\n", - " on_mouse_event_closure('motion_notify')\n", - " );\n", - "\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseenter',\n", - " on_mouse_event_closure('figure_enter')\n", - " );\n", - " rubberband_canvas.addEventListener(\n", - " 'mouseleave',\n", - " on_mouse_event_closure('figure_leave')\n", - " );\n", - "\n", - " canvas_div.addEventListener('wheel', function (event) {\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " on_mouse_event_closure('scroll')(event);\n", - " });\n", - "\n", - " canvas_div.appendChild(canvas);\n", - " canvas_div.appendChild(rubberband_canvas);\n", - "\n", - " this.rubberband_context = rubberband_canvas.getContext('2d');\n", - " this.rubberband_context.strokeStyle = '#000000';\n", - "\n", - " this._resize_canvas = function (width, height, forward) {\n", - " if (forward) {\n", - " canvas_div.style.width = width + 'px';\n", - " canvas_div.style.height = height + 'px';\n", - " }\n", - " };\n", - "\n", - " // Disable right mouse context menu.\n", - " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n", - " event.preventDefault();\n", - " return false;\n", - " });\n", - "\n", - " function set_focus() {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'mpl-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'mpl-button-group';\n", - " continue;\n", - " }\n", - "\n", - " var button = (fig.buttons[name] = document.createElement('button'));\n", - " button.classList = 'mpl-widget';\n", - " button.setAttribute('role', 'button');\n", - " button.setAttribute('aria-disabled', 'false');\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - "\n", - " var icon_img = document.createElement('img');\n", - " icon_img.src = '_images/' + image + '.png';\n", - " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", - " icon_img.alt = tooltip;\n", - " button.appendChild(icon_img);\n", - "\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " var fmt_picker = document.createElement('select');\n", - " fmt_picker.classList = 'mpl-widget';\n", - " toolbar.appendChild(fmt_picker);\n", - " this.format_dropdown = fmt_picker;\n", - "\n", - " for (var ind in mpl.extensions) {\n", - " var fmt = mpl.extensions[ind];\n", - " var option = document.createElement('option');\n", - " option.selected = fmt === mpl.default_extension;\n", - " option.innerHTML = fmt;\n", - " fmt_picker.appendChild(option);\n", - " }\n", - "\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "};\n", - "\n", - "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", - " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", - " // which will in turn request a refresh of the image.\n", - " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", - "};\n", - "\n", - "mpl.figure.prototype.send_message = function (type, properties) {\n", - " properties['type'] = type;\n", - " properties['figure_id'] = this.id;\n", - " this.ws.send(JSON.stringify(properties));\n", - "};\n", - "\n", - "mpl.figure.prototype.send_draw_message = function () {\n", - " if (!this.waiting) {\n", - " this.waiting = true;\n", - " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " var format_dropdown = fig.format_dropdown;\n", - " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", - " fig.ondownload(fig, format);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", - " var size = msg['size'];\n", - " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", - " fig._resize_canvas(size[0], size[1], msg['forward']);\n", - " fig.send_message('refresh', {});\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", - " var x0 = msg['x0'] / fig.ratio;\n", - " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", - " var x1 = msg['x1'] / fig.ratio;\n", - " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", - " x0 = Math.floor(x0) + 0.5;\n", - " y0 = Math.floor(y0) + 0.5;\n", - " x1 = Math.floor(x1) + 0.5;\n", - " y1 = Math.floor(y1) + 0.5;\n", - " var min_x = Math.min(x0, x1);\n", - " var min_y = Math.min(y0, y1);\n", - " var width = Math.abs(x1 - x0);\n", - " var height = Math.abs(y1 - y0);\n", - "\n", - " fig.rubberband_context.clearRect(\n", - " 0,\n", - " 0,\n", - " fig.canvas.width / fig.ratio,\n", - " fig.canvas.height / fig.ratio\n", - " );\n", - "\n", - " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", - " // Updates the figure title.\n", - " fig.header.textContent = msg['label'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", - " var cursor = msg['cursor'];\n", - " switch (cursor) {\n", - " case 0:\n", - " cursor = 'pointer';\n", - " break;\n", - " case 1:\n", - " cursor = 'default';\n", - " break;\n", - " case 2:\n", - " cursor = 'crosshair';\n", - " break;\n", - " case 3:\n", - " cursor = 'move';\n", - " break;\n", - " }\n", - " fig.rubberband_canvas.style.cursor = cursor;\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_message = function (fig, msg) {\n", - " fig.message.textContent = msg['message'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", - " // Request the server to send over a new figure.\n", - " fig.send_draw_message();\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", - " fig.image_mode = msg['mode'];\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", - " for (var key in msg) {\n", - " if (!(key in fig.buttons)) {\n", - " continue;\n", - " }\n", - " fig.buttons[key].disabled = !msg[key];\n", - " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", - " if (msg['mode'] === 'PAN') {\n", - " fig.buttons['Pan'].classList.add('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " } else if (msg['mode'] === 'ZOOM') {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.add('active');\n", - " } else {\n", - " fig.buttons['Pan'].classList.remove('active');\n", - " fig.buttons['Zoom'].classList.remove('active');\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Called whenever the canvas gets updated.\n", - " this.send_message('ack', {});\n", - "};\n", - "\n", - "// A function to construct a web socket function for onmessage handling.\n", - "// Called in the figure constructor.\n", - "mpl.figure.prototype._make_on_message_function = function (fig) {\n", - " return function socket_on_message(evt) {\n", - " if (evt.data instanceof Blob) {\n", - " /* FIXME: We get \"Resource interpreted as Image but\n", - " * transferred with MIME type text/plain:\" errors on\n", - " * Chrome. But how to set the MIME type? It doesn't seem\n", - " * to be part of the websocket stream */\n", - " evt.data.type = 'image/png';\n", - "\n", - " /* Free the memory for the previous frames */\n", - " if (fig.imageObj.src) {\n", - " (window.URL || window.webkitURL).revokeObjectURL(\n", - " fig.imageObj.src\n", - " );\n", - " }\n", - "\n", - " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", - " evt.data\n", - " );\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " } else if (\n", - " typeof evt.data === 'string' &&\n", - " evt.data.slice(0, 21) === 'data:image/png;base64'\n", - " ) {\n", - " fig.imageObj.src = evt.data;\n", - " fig.updated_canvas_event();\n", - " fig.waiting = false;\n", - " return;\n", - " }\n", - "\n", - " var msg = JSON.parse(evt.data);\n", - " var msg_type = msg['type'];\n", - "\n", - " // Call the \"handle_{type}\" callback, which takes\n", - " // the figure and JSON message as its only arguments.\n", - " try {\n", - " var callback = fig['handle_' + msg_type];\n", - " } catch (e) {\n", - " console.log(\n", - " \"No handler for the '\" + msg_type + \"' message type: \",\n", - " msg\n", - " );\n", - " return;\n", - " }\n", - "\n", - " if (callback) {\n", - " try {\n", - " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", - " callback(fig, msg);\n", - " } catch (e) {\n", - " console.log(\n", - " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", - " e,\n", - " e.stack,\n", - " msg\n", - " );\n", - " }\n", - " }\n", - " };\n", - "};\n", - "\n", - "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", - "mpl.findpos = function (e) {\n", - " //this section is from http://www.quirksmode.org/js/events_properties.html\n", - " var targ;\n", - " if (!e) {\n", - " e = window.event;\n", - " }\n", - " if (e.target) {\n", - " targ = e.target;\n", - " } else if (e.srcElement) {\n", - " targ = e.srcElement;\n", - " }\n", - " if (targ.nodeType === 3) {\n", - " // defeat Safari bug\n", - " targ = targ.parentNode;\n", - " }\n", - "\n", - " // pageX,Y are the mouse positions relative to the document\n", - " var boundingRect = targ.getBoundingClientRect();\n", - " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n", - " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n", - "\n", - " return { x: x, y: y };\n", - "};\n", - "\n", - "/*\n", - " * return a copy of an object with only non-object keys\n", - " * we need this to avoid circular references\n", - " * http://stackoverflow.com/a/24161582/3208463\n", - " */\n", - "function simpleKeys(original) {\n", - " return Object.keys(original).reduce(function (obj, key) {\n", - " if (typeof original[key] !== 'object') {\n", - " obj[key] = original[key];\n", - " }\n", - " return obj;\n", - " }, {});\n", - "}\n", - "\n", - "mpl.figure.prototype.mouse_event = function (event, name) {\n", - " var canvas_pos = mpl.findpos(event);\n", - "\n", - " if (name === 'button_press') {\n", - " this.canvas.focus();\n", - " this.canvas_div.focus();\n", - " }\n", - "\n", - " var x = canvas_pos.x * this.ratio;\n", - " var y = canvas_pos.y * this.ratio;\n", - "\n", - " this.send_message(name, {\n", - " x: x,\n", - " y: y,\n", - " button: event.button,\n", - " step: event.step,\n", - " guiEvent: simpleKeys(event),\n", - " });\n", - "\n", - " /* This prevents the web browser from automatically changing to\n", - " * the text insertion cursor when the button is pressed. We want\n", - " * to control all of the cursor setting manually through the\n", - " * 'cursor' event from matplotlib */\n", - " event.preventDefault();\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", - " // Handle any extra behaviour associated with a key event\n", - "};\n", - "\n", - "mpl.figure.prototype.key_event = function (event, name) {\n", - " // Prevent repeat events\n", - " if (name === 'key_press') {\n", - " if (event.which === this._key) {\n", - " return;\n", - " } else {\n", - " this._key = event.which;\n", - " }\n", - " }\n", - " if (name === 'key_release') {\n", - " this._key = null;\n", - " }\n", - "\n", - " var value = '';\n", - " if (event.ctrlKey && event.which !== 17) {\n", - " value += 'ctrl+';\n", - " }\n", - " if (event.altKey && event.which !== 18) {\n", - " value += 'alt+';\n", - " }\n", - " if (event.shiftKey && event.which !== 16) {\n", - " value += 'shift+';\n", - " }\n", - "\n", - " value += 'k';\n", - " value += event.which.toString();\n", - "\n", - " this._key_event_extra(event, name);\n", - "\n", - " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", - " return false;\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", - " if (name === 'download') {\n", - " this.handle_save(this, null);\n", - " } else {\n", - " this.send_message('toolbar_button', { name: name });\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", - " this.message.textContent = tooltip;\n", - "};\n", - "\n", - "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", - "// prettier-ignore\n", - "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", - "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", - "\n", - "mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", - "\n", - "mpl.default_extension = \"png\";/* global mpl */\n", - "\n", - "var comm_websocket_adapter = function (comm) {\n", - " // Create a \"websocket\"-like object which calls the given IPython comm\n", - " // object with the appropriate methods. Currently this is a non binary\n", - " // socket, so there is still some room for performance tuning.\n", - " var ws = {};\n", - "\n", - " ws.close = function () {\n", - " comm.close();\n", - " };\n", - " ws.send = function (m) {\n", - " //console.log('sending', m);\n", - " comm.send(m);\n", - " };\n", - " // Register the callback with on_msg.\n", - " comm.on_msg(function (msg) {\n", - " //console.log('receiving', msg['content']['data'], msg);\n", - " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", - " ws.onmessage(msg['content']['data']);\n", - " });\n", - " return ws;\n", - "};\n", - "\n", - "mpl.mpl_figure_comm = function (comm, msg) {\n", - " // This is the function which gets called when the mpl process\n", - " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", - "\n", - " var id = msg.content.data.id;\n", - " // Get hold of the div created by the display call when the Comm\n", - " // socket was opened in Python.\n", - " var element = document.getElementById(id);\n", - " var ws_proxy = comm_websocket_adapter(comm);\n", - "\n", - " function ondownload(figure, _format) {\n", - " window.open(figure.canvas.toDataURL());\n", - " }\n", - "\n", - " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", - "\n", - " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", - " // web socket which is closed, not our websocket->open comm proxy.\n", - " ws_proxy.onopen();\n", - "\n", - " fig.parent_element = element;\n", - " fig.cell_info = mpl.find_output_cell(\"
\");\n", - " if (!fig.cell_info) {\n", - " console.error('Failed to find cell for figure', id, fig);\n", - " return;\n", - " }\n", - " fig.cell_info[0].output_area.element.on(\n", - " 'cleared',\n", - " { fig: fig },\n", - " fig._remove_fig_handler\n", - " );\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_close = function (fig, msg) {\n", - " var width = fig.canvas.width / fig.ratio;\n", - " fig.cell_info[0].output_area.element.off(\n", - " 'cleared',\n", - " fig._remove_fig_handler\n", - " );\n", - " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", - "\n", - " // Update the output cell to use the data from the current canvas.\n", - " fig.push_to_output();\n", - " var dataURL = fig.canvas.toDataURL();\n", - " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", - " // the notebook keyboard shortcuts fail.\n", - " IPython.keyboard_manager.enable();\n", - " fig.parent_element.innerHTML =\n", - " '';\n", - " fig.close_ws(fig, msg);\n", - "};\n", - "\n", - "mpl.figure.prototype.close_ws = function (fig, msg) {\n", - " fig.send_message('closing', msg);\n", - " // fig.ws.close()\n", - "};\n", - "\n", - "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", - " // Turn the data on the canvas into data in the output cell.\n", - " var width = this.canvas.width / this.ratio;\n", - " var dataURL = this.canvas.toDataURL();\n", - " this.cell_info[1]['text/html'] =\n", - " '';\n", - "};\n", - "\n", - "mpl.figure.prototype.updated_canvas_event = function () {\n", - " // Tell IPython that the notebook contents must change.\n", - " IPython.notebook.set_dirty(true);\n", - " this.send_message('ack', {});\n", - " var fig = this;\n", - " // Wait a second, then push the new image to the DOM so\n", - " // that it is saved nicely (might be nice to debounce this).\n", - " setTimeout(function () {\n", - " fig.push_to_output();\n", - " }, 1000);\n", - "};\n", - "\n", - "mpl.figure.prototype._init_toolbar = function () {\n", - " var fig = this;\n", - "\n", - " var toolbar = document.createElement('div');\n", - " toolbar.classList = 'btn-toolbar';\n", - " this.root.appendChild(toolbar);\n", - "\n", - " function on_click_closure(name) {\n", - " return function (_event) {\n", - " return fig.toolbar_button_onclick(name);\n", - " };\n", - " }\n", - "\n", - " function on_mouseover_closure(tooltip) {\n", - " return function (event) {\n", - " if (!event.currentTarget.disabled) {\n", - " return fig.toolbar_button_onmouseover(tooltip);\n", - " }\n", - " };\n", - " }\n", - "\n", - " fig.buttons = {};\n", - " var buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " var button;\n", - " for (var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " /* Instead of a spacer, we start a new button group. */\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - " buttonGroup = document.createElement('div');\n", - " buttonGroup.classList = 'btn-group';\n", - " continue;\n", - " }\n", - "\n", - " button = fig.buttons[name] = document.createElement('button');\n", - " button.classList = 'btn btn-default';\n", - " button.href = '#';\n", - " button.title = name;\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', on_click_closure(method_name));\n", - " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", - " buttonGroup.appendChild(button);\n", - " }\n", - "\n", - " if (buttonGroup.hasChildNodes()) {\n", - " toolbar.appendChild(buttonGroup);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = document.createElement('span');\n", - " status_bar.classList = 'mpl-message pull-right';\n", - " toolbar.appendChild(status_bar);\n", - " this.message = status_bar;\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = document.createElement('div');\n", - " buttongrp.classList = 'btn-group inline pull-right';\n", - " button = document.createElement('button');\n", - " button.classList = 'btn btn-mini btn-primary';\n", - " button.href = '#';\n", - " button.title = 'Stop Interaction';\n", - " button.innerHTML = '';\n", - " button.addEventListener('click', function (_evt) {\n", - " fig.handle_close(fig, {});\n", - " });\n", - " button.addEventListener(\n", - " 'mouseover',\n", - " on_mouseover_closure('Stop Interaction')\n", - " );\n", - " buttongrp.appendChild(button);\n", - " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", - " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", - "};\n", - "\n", - "mpl.figure.prototype._remove_fig_handler = function (event) {\n", - " var fig = event.data.fig;\n", - " if (event.target !== this) {\n", - " // Ignore bubbled events from children.\n", - " return;\n", - " }\n", - " fig.close_ws(fig, {});\n", - "};\n", - "\n", - "mpl.figure.prototype._root_extra_style = function (el) {\n", - " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", - "};\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function (el) {\n", - " // this is important to make the div 'focusable\n", - " el.setAttribute('tabindex', 0);\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " } else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", - " var manager = IPython.notebook.keyboard_manager;\n", - " if (!manager) {\n", - " manager = IPython.keyboard_manager;\n", - " }\n", - "\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which === 13) {\n", - " this.canvas_div.blur();\n", - " // select the cell after this one\n", - " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", - " IPython.notebook.select(index + 1);\n", - " }\n", - "};\n", - "\n", - "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", - " fig.ondownload(fig, null);\n", - "};\n", - "\n", - "mpl.find_output_cell = function (html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i = 0; i < ncells; i++) {\n", - " var cell = cells[i];\n", - " if (cell.cell_type === 'code') {\n", - " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", - " var data = cell.output_area.outputs[j];\n", - " if (data.data) {\n", - " // IPython >= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] === html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "};\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel !== null) {\n", - " IPython.notebook.kernel.comm_manager.register_target(\n", - " 'matplotlib',\n", - " mpl.mpl_figure_comm\n", - " );\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" } ], "source": [ "# Setup to analyse an MDP Playground experiment\n", "from mdp_playground.analysis import MDPP_Analysis\n", "# Set dir_name to the location where the CSV files from running an experiment were saved\n", - "dir_name = '../mdp_files/'\n", + "dir_name = '/home/rajanr/mdpp_12744267_SAC_target_radius_can_use_as_sample/'\n", "# Set exp_name to the name that was given to the experiment when running it\n", - "exp_name = 'dqn_seq_del'\n", + "exp_name = 'sac_move_to_a_point_target_radius'\n", "# Set the following to True to save PDFs of plots that you generate below\n", "save_fig = True\n", "\n", + "files_dir = '/home/rajanr/mdpp_12744267_SAC_target_radius_can_use_as_sample/'\n", + "experiments = {\n", + " \"sac_move_to_a_point_target_radius\" : \"%s\"%files_dir,\n", + "# \"a3c_lstm_seq\" : \"%s/a3c_lstm_seq/\"%files_dir,\n", + "# \"a3c_del\" : \"%s/a3c_del/\"%files_dir,\n", + "# \"a3c_lstm_del\" : \"%s/a3c_lstm_del/\"%files_dir,\n", + "}\n", + "\n", + "\n", "from cave.cavefacade import CAVE\n", "from mdp_playground.analysis.mdpp_to_cave import MDPPToCave\n", "import os\n", "\n", "#The converted mdpp csvs will be stored in output_dir\n", - "output_dir = \"../mdpp_to_cave\"\n", + "output_dir = \"/home/rajanr/mdpp_to_cave\"\n", "mdpp_cave = MDPPToCave()\n", - "for exp_name, v in experiments.items():\n", - " dir_name, _ = os.path.split(v)\n", + "for exp_name, loc in experiments.items():\n", + " dir_name, _ = os.path.split(loc)\n", + " print(\"dir_name\", _, dir_name)\n", " cave_input_file = mdpp_cave.to_bohb_results(dir_name, exp_name, output_dir)\n", " print(cave_input_file)\n", " # Similarly, as an example, cave will ouput it's results \n", " # to the same directory as cave's input files\n", "\n", - " cave_results = os.path.join(cave_input_file, \"out\")\n", - " cave = CAVE(folders = [cave_input_file],\n", - " output_dir = cave_results,\n", - " ta_exec_dir = [cave_input_file],\n", - " file_format = \"BOHB\",\n", - " show_jupyter=True,\n", - " )\n", - " cave.performance_table()\n", - " cave.local_parameter_importance()\n", + "# cave_results = os.path.join(cave_input_file, \"out\")\n", + "# cave = CAVE(folders = [cave_input_file],\n", + "# output_dir = cave_results,\n", + "# ta_exec_dir = [cave_input_file],\n", + "# file_format = \"BOHB\",\n", + "# show_jupyter=True,\n", + "# )\n", + "# cave.performance_table()\n", + "# cave.local_parameter_importance()\n", " # cave.cave_fanova() # Only for experiments varying more than 1 meta-feature\n", "\n", "# Other analysis\n", @@ -4637,7 +521,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.12" + "version": "3.6.9" } }, "nbformat": 4, diff --git a/run_experiments.py b/run_experiments.py deleted file mode 100644 index 3501929..0000000 --- a/run_experiments.py +++ /dev/null @@ -1,58 +0,0 @@ -import sys, os -import argparse -import importlib - -def parse_args(): - parser = argparse.ArgumentParser(description=__doc__) # docstring at beginning of the file is stored in __doc__ - parser.add_argument('-c', '--config-file', dest='config_file', action='store', default='default_config', - help='Configuration file containing configuration to run experiments. It must be a Python file so config can be given programmatically. There are 2 types of configs - VARIABLE CONFIG across the experiments and STATIC CONFIG across the experiments. \nVARIABLE CONFIGS: The OrderedDicts var_env_configs, var_agent_configs and var_model_configs hold configuration options that are variable for the environment, agent and model across the current experiment. For each configuration option, the option is the key in the dict and its value is a list of values it can take for the current experiment. A Cartesian product of these lists is taken to generate various possible configurations to be run. For example, you might want to vary "delay" for the current experiment. Then "delay" would be a key in var_env_configs dict and its value would be a list of values it can take. Because Ray does not have a common way to address this specification of configurations for its agents, there are a few hacky ways to set var_agent_configs and var_model_configs currently. Please see sample experiment config files in the experiments directory to see how to set the values for a given algorithm. \nSTATIC CONFIGS: env_config, agent_config and model_config are dicts which hold the static configuration for the current experiment as a normal Python dict.') - parser.add_argument('-e', '--exp-name', dest='exp_name', action='store', default='mdpp_default_experiment', - help='The user-chosen name of the experiment. This is used as the prefix of the output files (the prefix also contains config_num if that is provided). It will save stats to 2 CSV files, with the filenames as the one given as argument' - ' and another file with an extra "_eval" in the filename that contains evaluation stats during the training. Appends to existing files or creates new ones if they don\'t exist.') - parser.add_argument('-n', '--config-num', dest='config_num', action='store', default=None, type=int, - help='Used for running the configurations of experiments in parallel. This is appended to the prefix of the output files (after exp_name).' - ' A Cartesian product of different configuration values for the experiment will be taken and ordered as a list and this number corresponds to the configuration number in this list.' - ' Please look in to the code for details.') - parser.add_argument('-fwk', '--framework', dest='framework', action='store', type=str, - help='Used to select the framework in which the experiments will be run, default value is ray. Options: ray, baselines') - - args = parser.parse_args() - print("Parsed args:", args) - return args - -def main(): - args = parse_args() - if args.framework is not None: # get from arguments - framework = args.framework - else: #check config file - if args.config_file[-3:] == '.py': - args.config_file = args.config_file[:-3] - config_file_path = os.path.abspath('/'.join(args.config_file.split('/')[:-1])) - sys.path.insert(1, config_file_path) - config = importlib.import_module(args.config_file.split('/')[-1], package=None) - try: - framework = config.framework - except AttributeError: - #Framework not defined either in args or config file - #set default value - framework = "ray" - - # Run file - print("Running framework:", framework) - if(framework == "stable_baselines"): - import run_experiments_baselines - run_experiments_baselines.main(args) - elif(framework == "stable_baselines3"): - import run_experiments_baselines3 - run_experiments_baselines3.main(args) - elif(framework == "custom"): - import run_experiments_custom - run_experiments_custom.main(args) - return - else: # ray - import run_experiments_ray - run_experiments_ray.main(args)#_ray.main(args) - - -if __name__ == '__main__': - main() \ No newline at end of file diff --git a/run_experiments_baselines.py b/run_experiments_baselines.py deleted file mode 100644 index 1eca51e..0000000 --- a/run_experiments_baselines.py +++ /dev/null @@ -1,141 +0,0 @@ -'''Script to run experiments on MDP Playground. - -Takes a configuration file, experiment name and config number to run as optional arguments. -''' -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function -from typing_extensions import final - -import numpy as np -import copy - -import mdp_playground -from mdp_playground.envs import RLToyEnv - -import sys, os -import argparse -import default_config -print("default_config:", default_config) - -import gym -from gym.wrappers.time_limit import TimeLimit - -import time -import pprint -import mdp_playground.config_processor.config_processor as config_processor -from mdp_playground.config_processor.baselines_processor import * -import logging -log_level_ = logging.WARNING - -def parse_args(): - parser = argparse.ArgumentParser(description=__doc__) # docstring at beginning of the file is stored in __doc__ - parser.add_argument('-c', '--config-file', dest='config_file', action='store', default='default_config', - help='Configuration file containing configuration to run experiments. It must be a Python file so config can be given programmatically. There are 2 types of configs - VARIABLE CONFIG across the experiments and STATIC CONFIG across the experiments. \nVARIABLE CONFIGS: The OrderedDicts var_env_configs, var_agent_configs and var_model_configs hold configuration options that are variable for the environment, agent and model across the current experiment. For each configuration option, the option is the key in the dict and its value is a list of values it can take for the current experiment. A Cartesian product of these lists is taken to generate various possible configurations to be run. For example, you might want to vary "delay" for the current experiment. Then "delay" would be a key in var_env_configs dict and its value would be a list of values it can take. Because Ray does not have a common way to address this specification of configurations for its agents, there are a few hacky ways to set var_agent_configs and var_model_configs currently. Please see sample experiment config files in the experiments directory to see how to set the values for a given algorithm. \nSTATIC CONFIGS: env_config, agent_config and model_config are dicts which hold the static configuration for the current experiment as a normal Python dict.') - parser.add_argument('-e', '--exp-name', dest='exp_name', action='store', default='mdpp_default_experiment', - help='The user-chosen name of the experiment. This is used as the prefix of the output files (the prefix also contains config_num if that is provided). It will save stats to 2 CSV files, with the filenames as the one given as argument' - ' and another file with an extra "_eval" in the filename that contains evaluation stats during the training. Appends to existing files or creates new ones if they don\'t exist.') - parser.add_argument('-n', '--config-num', dest='config_num', action='store', default=None, type=int, - help='Used for running the configurations of experiments in parallel. This is appended to the prefix of the output files (after exp_name).' - ' A Cartesian product of different configuration values for the experiment will be taken and ordered as a list and this number corresponds to the configuration number in this list.' - ' Please look in to the code for details.') - args = parser.parse_args() - print("Parsed args:", args) - return args - - -def main(args): - # print("Config file", os.path.abspath(args.config_file)) # 'experiments/dqn_seq_del.py' - if args.config_file[-3:] == '.py': - config_file = args.config_file[:-3] - else: - config_file = args.config_file - - stats_file_name = os.path.abspath(args.exp_name) - if args.config_num is None: - stats_file_name = args.exp_name - else: - stats_file_name = args.exp_name + '_' + str(args.config_num) - print("Stats file being written to:", stats_file_name) - - # config_file_path = os.path.abspath('/'.join(args.config_file.split('/')[:-1])) - # print("config_file_path:", config_file_path) - - # sys.path.insert(1, config_file_path) # hack - # config = importlib.import_module(args.config_file.split('/')[-1], package=None) - # print("Number of seeds for environment:", config.num_seeds) - # print("Configuration numbers that will be run:", "all" if args.config_num is None else args.config_num) - - config, final_configs = \ - config_processor.process_configs(config_file, - stats_file_prefix=stats_file_name, - framework="stable_baselines", - config_num=args.config_num, - log_level=log_level_) - # ------------------------- Variable configurations ----------------------------# - print("Configuration number(s) that will be run:", "all" if args.config_num is None else args.config_num) - - - # ------------ Run every configuration ------------------ # - pp = pprint.PrettyPrinter(indent=4) - total_configs = len(final_configs) - config_algorithm = config.algorithm - eval_cfg = config.eval_config - for i, current_config in enumerate(final_configs): - print("Configuration: %d \t %d remaining" - % (i, total_configs - i)) - - # ------------ Env init ------------------ # - env_config = current_config['env_config'] - print("Env config:",) - pp.pprint(env_config) - env, eval_env = \ - init_environments(config_algorithm, - current_config, - env_config, - eval_cfg["evaluation_config"]) - # ------------ Agent init ------------------ # - # Create the agent - timesteps_per_iteration = current_config["timesteps_per_iteration"] - model = init_agent(env, - config_algorithm, - current_config["model"], - current_config["agent"]) - - # ------------ train/evaluation ------------------ # - timesteps_total = config.timesteps_total - - # train your model for n_iter timesteps - # Define evaluation - # every x training iterations - eval_interval = eval_cfg["evaluation_interval"] - stats_file_name = current_config["stats_file_name"] - var_configs_deepcopy = current_config["var_configs_deepcopy"] - csv_callbacks = CustomCallback(eval_env, - n_eval_episodes=10, - timesteps_per_iteration=timesteps_per_iteration, - eval_interval=eval_interval, - deterministic=True, - file_name=stats_file_name, - config_algorithm=config_algorithm, - var_configs=var_configs_deepcopy) - # Train - learn_params = {"callback": csv_callbacks, - "total_timesteps": int(timesteps_total)} - if(config_algorithm == "DDPG"): - # Log interval is handled differently for each algorithm, - # e.g. each log_interval episodes(DQN) or log_interval steps(DDPG). - learn_params["log_interval"] = timesteps_per_iteration - else: - learn_params["log_interval"] = timesteps_per_iteration//10 - - model.learn(**learn_params) - model.save('%s_last' % (args.exp_name)) - - end = time.time() - print("No. of seconds to run:", end - start) - - -if __name__ == '__main__': - args = parse_args() - main(args) diff --git a/run_experiments_baselines3.py b/run_experiments_baselines3.py deleted file mode 100644 index 4511d5a..0000000 --- a/run_experiments_baselines3.py +++ /dev/null @@ -1,501 +0,0 @@ -'''Script to run experiments on MDP Playground. - -Takes a configuration file, experiment name and config number to run as optional arguments. -''' -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - -import numpy as np -import copy - -import mdp_playground -from mdp_playground.envs import RLToyEnv - -import sys, os -import argparse -import importlib - -import default_config -print("default_config:", default_config) - -import gym -from gym.wrappers.time_limit import TimeLimit - -import torch -import torch.nn as nn -from stable_baselines3.common.vec_env import DummyVecEnv -from stable_baselines3.common.monitor import Monitor -from stable_baselines3 import PPO, DQN, DDPG, SAC, A2C, TD3 -from stable_baselines3.common.callbacks import EveryNTimesteps, BaseCallback -from stable_baselines3.common.torch_layers import BaseFeaturesExtractor -from stable_baselines3.common.evaluation import evaluate_policy -from stable_baselines3.common.vec_env import DummyVecEnv, VecEnv, sync_envs_normalization -from typing import Any, Dict, List, Optional, Union - -from functools import reduce -import time -import itertools -import pprint - -#-------------- Custom Classes ------------# -class VisionNet(BaseFeaturesExtractor): - def __init__(self, observation_space: gym.spaces.Box, features_dim: int = 512, **kwargs): - super(VisionNet, self).__init__(observation_space, features_dim) - # We assume CxHxW images (channels first) - # Re-ordering will be done by pre-preprocessing or wrapper - - n_input_channels = observation_space.shape[0] - - if ("act_fun" in kwargs): - activ_fn = kwargs['activation_fun'] - else: #default - activ_fn = nn.ReLU - - #Create Cnn - modules = [] - for i, layer_def in enumerate(kwargs['cnn_layers']): - n_filters, kernel, padding = layer_def - modules.append(nn.Conv2d(n_input_channels, n_filters, kernel_size = kernel, stride = 1, padding = padding)) - modules.append(activ_fn()) - modules.append(nn.Flatten()) - self.cnn = nn.Sequential(*modules) - - # Compute shape by doing one forward pass - with torch.no_grad(): - n_flatten = self.cnn(torch.as_tensor(observation_space.sample()[None]).permute(0,-1, 1, 2).float()).shape[1] - - self.linear = nn.Sequential(nn.Linear(n_flatten, features_dim), activ_fn) - - def forward(self, observations: torch.Tensor) -> torch.Tensor: - return self.linear(self.cnn(observations.permute(0,-1, 1, 2))) - -class CustomCallback(BaseCallback): - """ - Callback for evaluating an agent. - :param eval_env: (Union[gym.Env, VecEnv]) The environment used for initialization - :param n_eval_episodes: (int) The number of episodes to test the agent - :param eval_freq: (int) Evaluate the agent every eval_freq call of the callback. - :param deterministic: (bool) Whether the evaluation should use a stochastic or deterministic actions. - :param verbose: (int) - """ - - def __init__( - self, - eval_env: Union[gym.Env, VecEnv], - n_eval_episodes: int = 5, - eval_freq: int = 10000, - deterministic: bool = True, - verbose: int = 1, - file_name: str = "./evaluation.csv", - config_algorithm: str ="" - ): - super(CustomCallback, self).__init__(verbose=verbose) - self.n_eval_episodes = n_eval_episodes - self.eval_freq = eval_freq - self.deterministic = deterministic - self.file_name = file_name - self.training_iteration = 0 - self.config_algorithm = config_algorithm - - # Convert to VecEnv for consistency - if not isinstance(eval_env, VecEnv): - eval_env = DummyVecEnv([lambda: eval_env]) - - if isinstance(eval_env, VecEnv): - assert eval_env.num_envs == 1, "You must pass only one environment for evaluation" - - self.eval_env = eval_env - - #evaluate policy when step % eval_freq == 0, return rewards and lengths list of n_eval_episodes elements - def _on_step(self) -> bool: - - if self.eval_freq > 0 and self.n_calls % self.eval_freq == 0: - # Sync training and eval env if there is VecNormalize - sync_envs_normalization(self.training_env, self.eval_env) - - episode_rewards, episode_lengths = evaluate_policy( - self.model, - self.eval_env, - n_eval_episodes=self.n_eval_episodes, - render=False, - deterministic=self.deterministic, - return_episode_rewards=True, - ) - - #Write train stats at the end of every training iteration - #on_train_result(self.training_env, self.training_iteration, self.file_name, self.config_algorithm) - self.training_iteration +=1 - #evaluation results - write_eval_stats(episode_rewards, episode_lengths, self.file_name) - - mean_reward, std_reward = np.mean(episode_rewards), np.std(episode_rewards) - mean_ep_length, std_ep_length = np.mean(episode_lengths), np.std(episode_lengths) - - if self.verbose > 0: - print(f"Eval num_timesteps={self.num_timesteps}, " f"episode_reward={mean_reward:.2f} +/- {std_reward:.2f}") - print(f"Episode length: {mean_ep_length:.2f} +/- {std_ep_length:.2f}") - return True - -#-------------- Custom Classes ------------# - -def parse_args(): - parser = argparse.ArgumentParser(description=__doc__) # docstring at beginning of the file is stored in __doc__ - parser.add_argument('-c', '--config-file', dest='config_file', action='store', default='default_config', - help='Configuration file containing configuration to run experiments. It must be a Python file so config can be given programmatically. There are 2 types of configs - VARIABLE CONFIG across the experiments and STATIC CONFIG across the experiments. \nVARIABLE CONFIGS: The OrderedDicts var_env_configs, var_agent_configs and var_model_configs hold configuration options that are variable for the environment, agent and model across the current experiment. For each configuration option, the option is the key in the dict and its value is a list of values it can take for the current experiment. A Cartesian product of these lists is taken to generate various possible configurations to be run. For example, you might want to vary "delay" for the current experiment. Then "delay" would be a key in var_env_configs dict and its value would be a list of values it can take. Because Ray does not have a common way to address this specification of configurations for its agents, there are a few hacky ways to set var_agent_configs and var_model_configs currently. Please see sample experiment config files in the experiments directory to see how to set the values for a given algorithm. \nSTATIC CONFIGS: env_config, agent_config and model_config are dicts which hold the static configuration for the current experiment as a normal Python dict.') - parser.add_argument('-e', '--exp-name', dest='exp_name', action='store', default='mdpp_default_experiment', - help='The user-chosen name of the experiment. This is used as the prefix of the output files (the prefix also contains config_num if that is provided). It will save stats to 2 CSV files, with the filenames as the one given as argument' - ' and another file with an extra "_eval" in the filename that contains evaluation stats during the training. Appends to existing files or creates new ones if they don\'t exist.') - parser.add_argument('-n', '--config-num', dest='config_num', action='store', default=None, type=int, - help='Used for running the configurations of experiments in parallel. This is appended to the prefix of the output files (after exp_name).' - ' A Cartesian product of different configuration values for the experiment will be taken and ordered as a list and this number corresponds to the configuration number in this list.' - ' Please look in to the code for details.') - # parser.add_argument('-t', '--tune-hps', dest='tune_hps', action='store', default=False, type=bool, - # help='Used for tuning the hyperparameters that can be used for experiments later.' - # ' A Cartesian product of different configuration values for the experiment will be taken and ordered as a list and this number corresponds to the configuration number in this list.' - # ' Please look in to the code for details.') - args = parser.parse_args() - print("Parsed args:", args) - return args - -# Callback to write training stats to CSV file at end of every training iteration -def on_train_result(train_env, training_iteration, filename, config_algorithm): - # Writes every iteration, would slow things down. #hack - fout = open(filename, 'a') #hardcoded - fout.write(str(training_iteration) + ' ' + config_algorithm + ' ') - for config_type, config_dict in var_configs_deepcopy.items(): - for key in config_dict: - if config_type == "env": - if key == 'reward_noise': - fout.write(str(info["result"]["config"]["env_config"]['reward_noise_std']) + ' ') #hack - elif key == 'transition_noise' and info["result"]["config"]["env_config"]["state_space_type"] == "continuous": - fout.write(str(info["result"]["config"]["env_config"]['transition_noise_std']) + ' ') #hack - else: - fout.write(str(info["result"]["config"]["env_config"][key]).replace(' ', '') + ' ') - elif config_type == "agent": - if config_algorithm == 'SAC' and key == "critic_learning_rate": - real_key = "lr" #hack due to Ray's weird ConfigSpaces - fout.write(str(info["result"]["config"]['optimization'][key]).replace(' ', '') + ' ') - elif config_algorithm == 'SAC' and key == "fcnet_hiddens": - #hack due to Ray's weird ConfigSpaces - fout.write(str(info["result"]["config"]["Q_model"][key]).replace(' ', '') + ' ') - else: - fout.write(str(info["result"]["config"][key]).replace(' ', '') + ' ') - elif config_type == "model": - # if key == 'conv_filters': - fout.write(str(info["result"]["config"]["model"][key]).replace(' ', '') + ' ') - - # Write train stats - timesteps_total = info["result"]["timesteps_total"] # also has episodes_total and training_iteration - episode_reward_mean = info["result"]["episode_reward_mean"] # also has max and min - # print("Custom_metrics: ", info["result"]["step_reward_mean"], info["result"]["step_reward_max"], info["result"]["step_reward_min"]) - episode_len_mean = info["result"]["episode_len_mean"] - - fout.write(str(timesteps_total) + ' ' + str(episode_reward_mean) + - ' ' + str(episode_len_mean) + '\n') # timesteps_total always HAS to be the 1st written: analysis.py depends on it - fout.close() - - # print("##### hack_filename: ", hack_filename) - # print(os.getcwd()) - - # We did not manage to find an easy way to log evaluation stats for Ray without the following hack which demarcates the end of a training iteration in the evaluation stats file - hack_filename_eval = stats_file_name + '_eval.csv' - fout = open(hack_filename_eval, 'a') #hardcoded - fout.write('#HACK STRING EVAL' + "\n") - fout.close() - - info["result"]["callback_ok"] = True - -# Used in callback after every episode has ended during evaluation -# replaces: def on_episode_end(info) -def write_eval_stats(episode_rewards, episode_lengths, stats_file_name = ""): - eval_filename = stats_file_name + '_eval.csv' - fout = open(eval_filename, 'a') #hardcoded - for reward_this_episode, length_this_episode in zip(episode_rewards, episode_lengths): - fout.write(str(reward_this_episode) + ' ' + str(length_this_episode) + "\n") - fout.close() - -def deepmerge(a, b, path=None): - '''Merges dict b into dict a - - Based on: https://stackoverflow.com/questions/7204805/how-to-merge-dictionaries-of-dictionaries/7205107#7205107 - ''' - if path is None: path = [] - for key in b: - if key in a: - if isinstance(a[key], dict) and isinstance(b[key], dict): - deepmerge(a[key], b[key], path + [str(key)]) - elif a[key] == b[key]: - pass # same leaf value - else: - raise Exception('Conflict at %s' % '.'.join(path + [str(key)])) - else: - a[key] = b[key] - return a - -def cartesian_prod(args, config): - value_tuples = [] - for config_type, config_dict in config.var_configs.items(): - for key in config_dict: - assert type(config.var_configs[config_type][key]) == list, "var_config should be a dict of dicts with lists as the leaf values to allow each configuration option to take multiple possible values" - value_tuples.append(config.var_configs[config_type][key]) - - cartesian_product_configs = list(itertools.product(*value_tuples)) - print("Total number of configs. to run:", len(cartesian_product_configs)) - - if args.config_num is None: - pass - else: - cartesian_product_configs = [cartesian_product_configs[args.config_num]] - - return cartesian_product_configs - -def process_dictionaries(config, current_config, var_env_configs, var_agent_configs, var_model_configs): - algorithm = config.algorithm - agent_config = config.agent_config - model_config = config.model_config - env_config = config.env_config - - for config_type, config_dict in config.var_configs.items(): - for key in config_dict: - # if config_type == "env_config": # There is a dummy seed in the env_config because it's not used in the environment. It implies a different seed for the agent on every launch as the seed for Ray is not being set here. I faced problems with Ray's seeding process. - if config_type == "env": - if key == 'reward_noise': - reward_noise_ = current_config[list(var_env_configs).index(key)] # this works because env_configs are 1st in the OrderedDict - env_config["env_config"][key] = lambda a: a.normal(0, reward_noise_) - env_config["env_config"]['reward_noise_std'] = reward_noise_ #hack Needed to be able to write scalar value of std dev. to stats file instead of the lambda function above ###TODO Could remove the hack by creating a class for the noises and changing its repr() - elif key == 'transition_noise' and env_config["env_config"]["state_space_type"] == "continuous": - transition_noise_ = current_config[list(var_env_configs).index(key)] - env_config["env_config"][key] = lambda a: a.normal(0, transition_noise_) - env_config["env_config"]['transition_noise_std'] = transition_noise_ #hack - else: - env_config["env_config"][key] = current_config[list(var_env_configs).index(key)] - - elif config_type == "agent": - num_configs_done = len(list(var_env_configs)) - if algorithm == 'SAC' and key == 'critic_learning_rate': #hack - value = current_config[num_configs_done + list(config.var_configs[config_type]).index(key)] - agent_config['optimization'] = { - key: value, - 'actor_learning_rate': value, - 'entropy_learning_rate': value, - } - elif algorithm == 'SAC' and key == 'fcnet_hiddens': #hack - agent_config['Q_model'] = { - key: current_config[num_configs_done + list(config.var_configs[config_type]).index(key)], - "fcnet_activation": "relu", - } - agent_config['policy_model'] = { - key: current_config[num_configs_done + list(config.var_configs[config_type]).index(key)], - "fcnet_activation": "relu", - } - else: - agent_config[key] = current_config[num_configs_done + list(config.var_configs[config_type]).index(key)] - - elif config_type == "model": - num_configs_done = len(list(var_env_configs)) + len(list(var_agent_configs)) - model_config["model"][key] = current_config[num_configs_done + list(config.var_configs[config_type]).index(key)] - - #hacks begin: - if model_config["model"]["use_lstm"]: - model_config["model"]["max_seq_len"] = env_config["env_config"]["delay"] + env_config["env_config"]["sequence_length"] + 1 - - if algorithm == 'DDPG': ###TODO Find a better way to enforce these?? - agent_config["actor_lr"] = agent_config["critic_lr"] - agent_config["actor_hiddens"] = agent_config["critic_hiddens"] - elif algorithm == 'TD3': - agent_config["target_noise_clip"] = agent_config["target_noise_clip"] * agent_config["target_noise"] - - # else: #if algorithm == 'SAC': - if env_config["env_config"]["state_space_type"] == 'continuous': - env_config["env_config"]["action_space_dim"] = env_config["env_config"]["state_space_dim"] - - return agent_config, model_config, env_config, algorithm - -def act_fnc_from_name(key): - if(key == "tanh"): - return nn.Tanh - elif(key == "sigmoid"): - return nn.Sigmoid - elif(key == "leakyrelu"): - return nn.LeakyReLU - else: #default - return nn.ReLU - -def process_agent_dict(algorithm, agent_config, model_config, env): - policy_kwargs = {} - if algorithm == 'DQN': - #change keys in dictionaries to something baselines understands - valid_keys = ['buffer_size', "learning_starts", "tau","gamma", "train_freq", "gradient_steps", "n_episodes_rollout", "target_update_interval","exploration_fraction","exploration_initial_eps","exploration_final_eps","max_grad_norm","tensorboard_log","learning_rate","batch_size","target_update_interval","lr_schedule"] - - exchange_keys = [ - ('lr','learning_rate'), - ('train_batch_size', 'batch_size'), - ('target_network_update_freq','target_update_interval')] - for key_tuple in exchange_keys: - old_key, new_key = key_tuple - if(old_key in agent_config): - agent_config[new_key] = agent_config.pop(old_key) - #remove keys from dictionary which are not configurable by baselines - for key in list(agent_config.keys()): - if( key not in valid_keys ): - agent_config.pop(key) - - #-------------- Model configuration ------------# - #decide whether to use cnn or mlp, taken from ray code.. - # Discrete/1D obs-spaces. - if isinstance(env.observation_space, gym.spaces.Discrete) or \ - len(env.observation_space.shape) <= 2: - feat_ext ="MlpPolicy" - else:# Default Conv2D net. - feat_ext = "CnnPolicy" - agent_config['policy'] = feat_ext - cnn_config = {} - - if(feat_ext == "MlpPolicy"): #mlp config - if("fcnet_activation" in model_config['model']): - policy_kwargs['activation_fn'] = act_fnc_from_name( model_config['model']["fcnet_activation"]) - if("fcnet_hiddens" in model_config['model']): - policy_kwargs['net_arch'] = model_config['model']["fcnet_hiddens"] - #this is to create a custom CNN since there's no implementation currently - else: #cnn config - policy_kwargs['net_arch'] = model_config['model']["fcnet_hiddens"] - if("conv_activation" in model_config['model'] ): - cnn_config["activation_fn"] = act_fnc_from_name( model_config['model']["conv_activation"] ) - if("conv_filters" in model_config['model'] ): - cnn_config["cnn_layers"] = model_config['model']["conv_filters"] - - #custom - if( feat_ext == "CnnPolicy"): - policy_kwargs['features_extractor_class'] = VisionNet - policy_kwargs["features_extractor_kwargs"] = cnn_config - - #add policy arguments to agent configuration - if('lr_schedule'in agent_config.keys()): #schedule is part of model instead of agent in baselines - policy_kwargs['lr_schedule'] = agent_config['lr_schedule'] - agent_config['policy_kwargs'] = policy_kwargs - - return agent_config - -def main(args): - #print("Config file", os.path.abspath(args.config_file)) # 'experiments/dqn_seq_del.py' - if args.config_file[-3:] == '.py': - args.config_file = args.config_file[:-3] - - config_file_path = os.path.abspath('/'.join(args.config_file.split('/')[:-1])) - print("config_file_path:", config_file_path) - - sys.path.insert(1, config_file_path) #hack - config = importlib.import_module(args.config_file.split('/')[-1], package=None) - print("Number of seeds for environment:", config.num_seeds) - print("Configuration numbers that will be run:", "all" if args.config_num is None else args.config_num) - - args.exp_name = os.path.abspath(args.exp_name) - if args.config_num is None: - stats_file_name = args.exp_name - else: - stats_file_name = args.exp_name + '_' + str(args.config_num) - print("Stats file being written to:", stats_file_name) - - #------------------------- Variable configurations ----------------------------# - var_configs_deepcopy = copy.deepcopy(config.var_configs) - - if "env" in config.var_configs: - var_env_configs = config.var_configs["env"] #hack - else: - var_env_configs = [] - if "agent" in config.var_configs: - var_agent_configs = config.var_configs["agent"] #hack - else: - var_agent_configs = [] - if "model" in config.var_configs: - var_model_configs = config.var_configs["model"] #hack - else: - var_model_configs = [] - - print('# Algorithm, state_space_size, action_space_size, delay, sequence_length, reward_density, make_denser, terminal_state_density, transition_noise, reward_noise ') - - configs_to_print = '' - for config_type, config_dict in var_configs_deepcopy.items(): - if config_type == 'env': - for key in config_dict: - configs_to_print += str(config_dict[key]) + ', ' - - print(config.algorithm, configs_to_print) - - #----------------- Write headers to csv file --------------------# - hack_filename = stats_file_name + '.csv' - fout = open(hack_filename, 'a') #hardcoded - fout.write('# training_iteration, algorithm, ') - for config_type, config_dict in var_configs_deepcopy.items(): - for key in config_dict: - fout.write(key + ', ') - fout.write('timesteps_total, episode_reward_mean, episode_len_mean\n') - fout.close() - - #---------- Compute cartesian product of configs ----------------# - start = time.time() - cartesian_product_configs = cartesian_prod(args, config) - - #------------ Run every configuration ------------------ # - pp = pprint.PrettyPrinter(indent=4) - for current_config in cartesian_product_configs: - #------------ Dictionaries setup ------------------ # - agent_config, model_config, env_config, algorithm = process_dictionaries(config, current_config, var_env_configs, var_agent_configs, var_model_configs) #modify to match baselines syntax - - #------------ Env init ------------------ # - env = gym.make(env_config['env'],**env_config['env_config']) - env = Monitor(env, None) - - #Evaluation environment - #limit max timesteps in evaluation = horizon - eval_horizon = 100 - eval_env = gym.make(env_config['env'],**env_config['env_config']) - eval_env.spec.tags['wrapper_config.TimeLimit.max_episode_steps'] = eval_horizon - eval_env = TimeLimit(eval_env, max_episode_steps = eval_horizon) #horizon - print("Env config:",) - pp.pprint(env_config) - - #------------ Agent init ------------------ # - # Create the agent - timesteps_per_iteration = agent_config['timesteps_per_iteration'] - agent_config_p = process_agent_dict(algorithm, agent_config.copy(), model_config, env) - if config.algorithm == 'DQN': - model = DQN(env = env, **agent_config_p, verbose=1) - elif config.algorithm == 'DDPG': #hack - model = DDPG(env = env, **agent_config_p) - else: #'SAC' - model = SAC(env = env, **agent_config_p) - - #------------ evaluation / training ------------------ # - if env_config["env"] in ["HopperWrapper-v3", "HalfCheetahWrapper-v3"]: #hack - timesteps_total = 500000 - else: - if algorithm == 'DQN': - timesteps_total = 20000 - elif algorithm == 'A3C': #hack - timesteps_total = 150000 - else: #if algorithm == 'DDPG': #hack - timesteps_total = 20000 - - #Define evaluation - evaluation_interval = 1 #every x training iterations - eval_frequency = timesteps_per_iteration * evaluation_interval - eval_callback = CustomCallback(eval_env, n_eval_episodes=10, eval_freq=eval_frequency, \ - deterministic=True, file_name = stats_file_name, config_algorithm = algorithm) - #Train - model.learn(callback= eval_callback, total_timesteps = timesteps_total) - rewards = env.get_episode_rewards() - espisode_lengths = env.get_episode_lengths() - episode_times = env.get_episode_times() - total_steps = env.get_total_steps() - # Evaluate the agent at the end of training? - #mean_reward, std_reward = evaluate_policy(model, model.get_env(), n_eval_episodes=10) - - end = time.time() - print("No. of seconds to run:", end - start) - - -if __name__ == '__main__': - args = parse_args() - main(args) \ No newline at end of file diff --git a/run_experiments_ray.py b/run_experiments_ray.py deleted file mode 100644 index 30821a3..0000000 --- a/run_experiments_ray.py +++ /dev/null @@ -1,566 +0,0 @@ -'''Script to run experiments on MDP Playground. -Takes a configuration file, experiment name and config number to run as optional arguments. -''' -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - -import numpy as np -import copy -import warnings -import logging - -import ray -from ray import tune -from ray.rllib.utils.seed import seed as rllib_seed -import mdp_playground -from mdp_playground.envs import RLToyEnv -from ray.tune.registry import register_env -import sys, os -import argparse - -register_env("RLToy-v0", lambda config: RLToyEnv(**config)) -register_env("GymEnvWrapper-Atari", lambda config: create_gym_env_wrapper_atari(config)) -register_env("GymEnvWrapperFrameStack-Atari", lambda config: create_gym_env_wrapper_frame_stack_atari(config)) -register_env("RLToy-v0", lambda config: RLToyEnv(**config)) - -def create_gym_env_wrapper_atari(config): - from gym.envs.atari import AtariEnv - from mdp_playground.envs.gym_env_wrapper import GymEnvWrapper - ae = AtariEnv(**config["AtariEnv"]) - gew = GymEnvWrapper(ae, **config) ##IMP Had initially thought to put this config in config["GymEnvWrapper"] but because of code below which converts var_env_configs to env_config, it's best to leave those configs as top level configs in the dict! - return gew - - - -def create_gym_env_wrapper_frame_stack_atari(config): #hack ###TODO remove? - '''When using frameStack GymEnvWrapper should wrap AtariEnv using wrap_deepmind_ray and therefore this function sets "wrap_deepmind_ray": True and 'frame_skip': 1 inside config so as to keep config same as for create_gym_env_wrapper_atari above and reduce manual errors when switching between the 2. - ''' - config["wrap_deepmind_ray"] = True #hack - config["frame_skip"] = 1 #hack - from gym.envs.atari import AtariEnv - from mdp_playground.envs.gym_env_wrapper import GymEnvWrapper - import gym - game = config["AtariEnv"]["game"] - game = ''.join([g.capitalize() for g in game.split('_')]) - ae = gym.make('{}NoFrameskip-v4'.format(game)) - gew = GymEnvWrapper(ae, **config) ##IMP Had initially thought to put this config in config["GymEnvWrapper"] but because of code below which converts var_env_configs to env_config, it's best to leave those configs as top level configs in the dict! - return gew - - - -def parse_args(): - parser = argparse.ArgumentParser(description=__doc__) # docstring at beginning of the file is stored in __doc__ - parser.add_argument('-c', '--config-file', dest='config_file', action='store', default='default_config', - help='Configuration file containing configuration to run experiments. It must be a Python file so config can be given programmatically. There are 2 types of configs - VARIABLE CONFIG across the experiments and STATIC CONFIG across the experiments. \nVARIABLE CONFIGS: The OrderedDicts var_env_configs, var_agent_configs and var_model_configs hold configuration options that are variable for the environment, agent and model across the current experiment. For each configuration option, the option is the key in the dict and its value is a list of values it can take for the current experiment. A Cartesian product of these lists is taken to generate various possible configurations to be run. For example, you might want to vary "delay" for the current experiment. Then "delay" would be a key in var_env_configs dict and its value would be a list of values it can take. Because Ray does not have a common way to address this specification of configurations for its agents, there are a few hacky ways to set var_agent_configs and var_model_configs currently. Please see sample experiment config files in the experiments directory to see how to set the values for a given algorithm. \nSTATIC CONFIGS: env_config, agent_config and model_config are dicts which hold the static configuration for the current experiment as a normal Python dict.') ####TODO Update docs regarding how to get configs to run: i.e., Cartesian product, or random, etc. - parser.add_argument('-e', '--exp-name', dest='exp_name', action='store', default='mdpp_default_experiment', - help='The user-chosen name of the experiment. This is used as the prefix of the output files (the prefix also contains config_num if that is provided). It will save stats to 2 CSV files, with the filenames as the one given as argument' - ' and another file with an extra "_eval" in the filename that contains evaluation stats during the training. Appends to existing files or creates new ones if they don\'t exist.') - parser.add_argument('-n', '--config-num', dest='config_num', action='store', default=None, type=int, - help='Used for running the configurations of experiments in parallel. This is appended to the prefix of the output files (after exp_name).' - ' A Cartesian product of different configuration values for the experiment will be taken and ordered as a list and this number corresponds to the configuration number in this list.' - ' Please look in to the code for details.') - parser.add_argument('-a', '--agent-config-num', dest='agent_config_num', action='store', default=None, type=int, - help='Used for running the configurations of experiments in parallel. This is appended to the prefix of the output files (after exp_name).') ###TODO Remove? #hack to run 1000 x 1000 env configs x agent configs. Storing all million of them in memory may be too inefficient? - parser.add_argument('-m', '--save-model', dest='save_model', action='store', default=False, type=bool, - help='Option to save trained NN model at the end of training.') - parser.add_argument('-t', '--framework-dir', dest='framework_dir', action='store', default='/tmp/', type=str, - help='Prefix of directory to be used by underlying framework (e.g. Ray Rllib, Stable Baselines 3). This name will be passed to the framework.') - # parser.add_argument('-t', '--tune-hps', dest='tune_hps', action='store', default=False, type=bool, - # help='Used for tuning the hyperparameters that can be used for experiments later.' - # ' A Cartesian product of different configuration values for the experiment will be taken and ordered as a list and this number corresponds to the configuration number in this list.' - # ' Please look in to the code for details.') - - args = parser.parse_args() - print("Parsed args:", args) - return args - -def main(args): - - if args.config_file[-3:] == '.py': - args.config_file = args.config_file[:-3] - - config_file_path = os.path.abspath('/'.join(args.config_file.split('/')[:-1])) - # print("config_file_path:", config_file_path) - sys.path.insert(1, config_file_path) #hack - import importlib - config = importlib.import_module(args.config_file.split('/')[-1], package=None) - print("Number of seeds for environment:", config.num_seeds) - print("Configuration number(s) that will be run:", "all" if args.config_num is None else args.config_num) - - - # import default_config - # print("default_config:", default_config) - # print(os.path.abspath(args.config_file)) # 'experiments/dqn_seq_del.py' - - args.exp_name = os.path.abspath(args.exp_name) - stats_file_name = args.exp_name - - if args.config_num is not None: - stats_file_name += '_' + str(args.config_num) - # elif args.agent_config_num is not None: ###TODO Remove? If we append both these nums then, that can lead to 1M small files for 1000x1000 configs which doesn't play well with our Nemo cluster. - # stats_file_name += '_' + str(args.agent_config_num) - - print("Stats file being written to:", stats_file_name) - - - #TODO Different seeds for Ray Trainer (TF, numpy, Python; Torch, Env), Environment (it has multiple sources of randomness too), Ray Evaluator - from ray.rllib.models.preprocessors import OneHotPreprocessor - from ray.rllib.models import ModelCatalog - ModelCatalog.register_custom_preprocessor("ohe", OneHotPreprocessor) - - log_level_ = logging.WARNING ##TODO Make a runtime argument - - if config.algorithm == 'DQN': - ray.init(object_store_memory=int(2e9), redis_max_memory=int(1e9), temp_dir='/tmp/ray' + str(args.config_num), include_webui=False, logging_level=log_level_, local_mode=True) #webui_host='0.0.0.0'); logging_level=logging.INFO, - - # ray.init(object_store_memory=int(2e9), redis_max_memory=int(1e9), local_mode=True, plasma_directory='/tmp') #, memory=int(8e9), local_mode=True # local_mode (bool): If true, the code will be executed serially. This is useful for debugging. # when true on_train_result and on_episode_end operate in the same current directory as the script. A3C is crashing in local mode, so didn't use it and had to work around by giving full path + filename in stats_file_name.; also has argument driver_object_store_memory=, plasma_directory='/tmp' - elif config.algorithm == 'A3C': #hack - ray.init(object_store_memory=int(2e9), redis_max_memory=int(1e9), temp_dir='/tmp/ray' + str(args.config_num), include_webui=False, logging_level=log_level_) - # ray.init(object_store_memory=int(2e9), redis_max_memory=int(1e9), local_mode=True, plasma_directory='/tmp') - else: - ray.init(object_store_memory=int(2e9), redis_max_memory=int(1e9), local_mode=True, temp_dir='/tmp/ray' + str(args.config_num), include_webui=False, logging_level=log_level_) - - - var_configs_deepcopy = copy.deepcopy(config.var_configs) #hack because this needs to be read in on_train_result and trying to read config there raises an error because it's been imported from a Python module and I think they try to reload it there. - if "timesteps_total" in dir(config): - hacky_timesteps_total = config.timesteps_total #hack - - if "env" in config.var_configs: - var_env_configs = config.var_configs["env"] #hack - else: - var_env_configs = [] - if "agent" in config.var_configs: - var_agent_configs = config.var_configs["agent"] #hack - else: - var_agent_configs = [] - if "model" in config.var_configs: - var_model_configs = config.var_configs["model"] #hack - else: - var_model_configs = [] - - config_algorithm = config.algorithm #hack - # sys.exit(0) - - - print('# Algorithm, state_space_size, action_space_size, delay, sequence_length, reward_density, make_denser, terminal_state_density, transition_noise, reward_noise ') - - configs_to_print = '' - for config_type, config_dict in var_configs_deepcopy.items(): - if config_type == 'env': - for key in config_dict: - configs_to_print += str(config_dict[key]) + ', ' - - print(config.algorithm, configs_to_print) - - - hack_filename = stats_file_name + '.csv' - fout = open(hack_filename, 'a') #hardcoded - fout.write('# training_iteration, algorithm, ') - for config_type, config_dict in var_configs_deepcopy.items(): - for key in config_dict: - # if config_type == "agent": - # if config_algorithm == 'SAC' and key == "critic_learning_rate": - # real_key = "lr" #hack due to Ray's weird ConfigSpaces - # fout.write(real_key + ', ') - # elif config_algorithm == 'SAC' and key == "fcnet_hiddens": - # #hack due to Ray's weird ConfigSpaces - # fout.write('fcnet_hiddens' + ', ') - # else: - # fout.write(key + ', ') - # else: - fout.write(key + ', ') - fout.write('timesteps_total, episode_reward_mean, episode_len_mean\n') - fout.close() - - - import time - start = time.time() - - # Ray callback to write training stats to CSV file at end of every training iteration - def on_train_result(info): - training_iteration = info["result"]["training_iteration"] - # algorithm = info["trainer"]._name - - # Writes every iteration, would slow things down. #hack - fout = open(hack_filename, 'a') #hardcoded - fout.write(str(training_iteration) + ' ' + config_algorithm + ' ') - for config_type, config_dict in var_configs_deepcopy.items(): - for key in config_dict: - if config_type == "env": - if key == 'reward_noise': - fout.write('%.2e' % info["result"]["config"]["env_config"]['reward_noise_std'] + ' ') #hack - elif key == 'transition_noise' and info["result"]["config"]["env_config"]["state_space_type"] == "continuous": - fout.write('%.2e' % info["result"]["config"]["env_config"]['transition_noise_std'] + ' ') #hack - else: - field_val = info["result"]["config"]["env_config"][key] - if isinstance(field_val, float): - str_to_write = '%.2e' % field_val - elif type(field_val) == list: - str_to_write = "[" - for elem in field_val: - # print(key) - str_to_write += '%.2e' % elem if isinstance(elem, float) else str(elem) - str_to_write += "," - str_to_write += "]" - else: - str_to_write = str(field_val).replace(' ', '') - str_to_write += ' ' - fout.write(str_to_write) - elif config_type == "agent": - if config_algorithm == 'SAC' and key == "critic_learning_rate": - real_key = "lr" #hack due to Ray's weird ConfigSpaces - fout.write('%.2e' % info["result"]["config"]['optimization'][key].replace(' ', '') + ' ') - elif config_algorithm == 'SAC' and key == "fcnet_hiddens": - #hack due to Ray's weird ConfigSpaces - str_to_write = str(info["result"]["config"]["Q_model"][key]).replace(' ', '') + ' ' - fout.write(str_to_write) - # elif config_algorithm == 'SAC' and key == "policy_model": - # #hack due to Ray's weird ConfigSpaces - # pass - # fout.write(str(info["result"]["config"][key]['fcnet_hiddens']).replace(' ', '') + ' ') - else: - if key == "exploration_fraction" and "exploration_fraction" not in info["result"]["config"]: #hack ray 0.7.3 will have exploration_fraction but not versions later than ~0.9 - field_val = info["result"]["config"]["exploration_config"]["epsilon_timesteps"] / hacky_timesteps_total # convert to fraction to be similar to old exploration_fraction - else: - field_val = info["result"]["config"][key] - str_to_write = '%.2e' % field_val if isinstance(field_val, float) else str(field_val).replace(' ', '') - str_to_write += ' ' - fout.write(str_to_write) - elif config_type == "model": - # if key == 'conv_filters': - fout.write(str(info["result"]["config"]["model"][key]).replace(' ', '') + ' ') - - # Write train stats - timesteps_total = info["result"]["timesteps_total"] # also has episodes_total and training_iteration - episode_reward_mean = info["result"]["episode_reward_mean"] # also has max and min - # print("Custom_metrics: ", info["result"]["step_reward_mean"], info["result"]["step_reward_max"], info["result"]["step_reward_min"]) - episode_len_mean = info["result"]["episode_len_mean"] - - fout.write(str(timesteps_total) + ' ' + '%.2e' % episode_reward_mean + - ' ' + '%.2e' % episode_len_mean + '\n') # timesteps_total always HAS to be the 1st written: analysis.py depends on it - fout.close() - - # print("##### hack_filename: ", hack_filename) - # print(os.getcwd()) - - # We did not manage to find an easy way to log evaluation stats for Ray without the following hack which demarcates the end of a training iteration in the evaluation stats file - hack_filename_eval = stats_file_name + '_eval.csv' - fout = open(hack_filename_eval, 'a') #hardcoded - - import os, psutil - mem_used_mb = psutil.Process(os.getpid()).memory_info().rss / 1024 ** 2 - - fout.write('#HACK STRING EVAL, mem_used_mb: ' + str(mem_used_mb) + "\n") - fout.close() - - info["result"]["callback_ok"] = True - - - # Ray callback to write evaluation stats to CSV file at end of every training iteration - # on_episode_end is used because these results won't be available on_train_result but only after every episode has ended during evaluation (evaluation phase is checked for by using dummy_eval) - def on_episode_end(info): - if "dummy_eval" in info["env"].get_unwrapped()[0].config: - # print("###on_episode_end info", info["env"].get_unwrapped()[0].config["make_denser"], info["episode"].total_reward, info["episode"].length) #, info["episode"]._agent_reward_history) - reward_this_episode = info["episode"].total_reward - length_this_episode = info["episode"].length - hack_filename_eval = stats_file_name + '_eval.csv' - fout = open(hack_filename_eval, 'a') #hardcoded - fout.write('%.2e' % reward_this_episode + ' ' + str(length_this_episode) + "\n") - fout.close() - - def on_episode_step(info): - episode = info["episode"] - if "step_reward" not in episode.custom_metrics: - episode.custom_metrics["step_reward"] = [] - step_reward = episode.total_reward - else: - step_reward = episode.total_reward - np.sum(episode.custom_metrics["step_reward"]) - episode.custom_metrics["step_reward"].append(step_reward) # This line should not be executed the 1st time this function is called because no step has actually taken place then (Ray 0.9.0)!! - # episode.custom_metrics = {} - # episode.user_data = {} - # episode.hist_data = {} - # Next 2 are the same, except 1st one is total episodic reward _per_ agent - # episode.agent_rewards = defaultdict(float) - # episode.total_reward += reward - # only hack to get per step reward seems to be to store prev total_reward and subtract it from that - # episode._agent_reward_history[agent_id].append(reward) - - - - # value_tuples = [] - # for config_type, config_dict in config.var_configs.items(): - # for key in config_dict: - # assert type(config.var_configs[config_type][key]) == list, "var_config should be a dict of dicts with lists as the leaf values to allow each configuration option to take multiple possible values" - # value_tuples.append(config.var_configs[config_type][key]) - # - # import itertools - # cartesian_product_configs = list(itertools.product(*value_tuples)) - # print("Total number of configs. to run:", len(cartesian_product_configs)) - - if args.config_num is None: - cartesian_product_configs = config.cartesian_product_configs - # pass - else: - cartesian_product_configs = [config.cartesian_product_configs[args.config_num]] - - #hack ###TODO remove? - if 'random_configs' in dir(config): - random_configs = config.random_configs # [args.agent_config_num] - if args.agent_config_num is not None: - random_configs = [config.random_configs[args.agent_config_num]] - # print("Single random_config of agent to be run:", random_config) - else: - random_configs = [()] * len(cartesian_product_configs) - - - - from functools import reduce - def deepmerge(a, b, path=None): - '''Merges dict b into dict a - Based on: https://stackoverflow.com/questions/7204805/how-to-merge-dictionaries-of-dictionaries/7205107#7205107 - ''' - if path is None: path = [] - for key in b: - if key in a: - if isinstance(a[key], dict) and isinstance(b[key], dict): - deepmerge(a[key], b[key], path + [str(key)]) - elif a[key] == b[key]: - pass # same leaf value - else: - raise Exception('Conflict at %s' % '.'.join(path + [str(key)])) - else: - a[key] = b[key] - return a - - import pprint - pp = pprint.PrettyPrinter(indent=4) - - for enum_conf_1, current_config_ in enumerate(cartesian_product_configs): - for enum_conf_2, random_config_ in enumerate(random_configs): - print("current_config of agent to be run:", current_config_, enum_conf_1) - print("random_config of agent to be run:", random_config_, enum_conf_2) - - current_config = current_config_ + random_config_ ###TODO Remove #hack because this ignores model_config that may be at end of current_config! - algorithm = config.algorithm - - agent_config = config.agent_config - model_config = config.model_config - env_config = config.env_config - # sys.exit(0) - - for config_type, config_dict in config.var_configs.items(): - for key in config_dict: - # if config_type == "env_config": # There is a dummy seed in the env_config because it's not used in the environment. It implies a different seed for the agent on every launch as the seed for Ray is not being set here. I faced problems with Ray's seeding process. - if config_type == "env": #hack All these are hacks to get around different limitations - if key == 'reward_noise': - reward_noise_ = current_config[list(var_env_configs).index(key)] # this works because env_configs are 1st in the OrderedDict - env_config["env_config"][key] = tune.function(lambda a: a.normal(0, reward_noise_)) - env_config["env_config"]['reward_noise_std'] = reward_noise_ #hack Needed to be able to write scalar value of std dev. to stats file instead of the lambda function above ###TODO Could remove the hack by creating a class for the noises and changing its repr() - elif key == 'transition_noise' and env_config["env_config"]["state_space_type"] == "continuous": - transition_noise_ = current_config[list(var_env_configs).index(key)] - env_config["env_config"][key] = tune.function(lambda a: a.normal(0, transition_noise_)) - env_config["env_config"]['transition_noise_std'] = transition_noise_ #hack - elif key == 'reward_dist_end_pts': - reward_dist_ = current_config[list(var_env_configs).index(key)] # this works because env_configs are 1st in the OrderedDict - - permutations = [] - length = current_config[list(var_env_configs).index("sequence_length")] - diameter = current_config[list(var_env_configs).index("diameter")] - action_space_size = current_config[list(var_env_configs).index("action_space_size")] - state_space_size = action_space_size * diameter - terminal_state_density = current_config[list(var_env_configs).index("terminal_state_density")] - maximum = state_space_size * (1 - terminal_state_density)/diameter - fraction = current_config[list(var_env_configs).index("reward_density")] - - for i in range(length): - permutations.append(maximum - i // diameter) - num_possible_permutations = np.prod(permutations) - num_sel_sequences = int(fraction * num_possible_permutations) - if num_sel_sequences == 0: - num_sel_sequences = 1 - warnings.warn('0 rewardable sequences per independent set for given reward_density, sequence_length, diameter and terminal_state_density. Setting it to 1.') - - num_rews = diameter * num_sel_sequences - print("num_rewardable_sequences set to:", num_rews) - if num_rews == 1: - rews = [1.0] - else: - rews = np.linspace(reward_dist_[0], reward_dist_[1], num=num_rews) - assert rews[-1] == 1.0 - np.random.shuffle(rews) - - def get_rews(rng, r_dict): - return rews[len(r_dict)] - - env_config["env_config"]['reward_dist'] = tune.function(get_rews) - env_config["env_config"]['reward_dist_end_pts'] = reward_dist_ - env_config["env_config"]['state_space_size'] = action_space_size * diameter - else: - env_config["env_config"][key] = current_config[list(var_env_configs).index(key)] - - elif config_type == "agent": - num_configs_done = len(list(var_env_configs)) - if algorithm == 'SAC' and key == 'critic_learning_rate': #hack - value = current_config[num_configs_done + list(config.var_configs[config_type]).index(key)] - agent_config['optimization'] = { - key: value, - 'actor_learning_rate': value, - 'entropy_learning_rate': value, - } - elif algorithm == 'SAC' and key == 'fcnet_hiddens': #hack - agent_config['Q_model'] = { - key: current_config[num_configs_done + list(config.var_configs[config_type]).index(key)], - "fcnet_activation": "relu", - } - agent_config['policy_model'] = { - key: current_config[num_configs_done + list(config.var_configs[config_type]).index(key)], - "fcnet_activation": "relu", - } - else: - agent_config[key] = current_config[num_configs_done + list(config.var_configs[config_type]).index(key)] - - elif config_type == "model": - num_configs_done = len(list(var_env_configs)) + len(list(var_agent_configs)) - model_config["model"][key] = current_config[num_configs_done + list(config.var_configs[config_type]).index(key)] - - #hacks begin: - if "model" in model_config and model_config["model"]["use_lstm"]: - model_config["model"]["max_seq_len"] = env_config["env_config"]["delay"] + env_config["env_config"]["sequence_length"] + 1 - - if algorithm == 'DDPG': ###TODO Find a better way to enforce these?? Especially problematic for TD3 because then more values for target_noise_clip are witten to CSVs than actually used during HPO but for normal (non-HPO) runs this needs to be not done. - agent_config["actor_lr"] = agent_config["critic_lr"] - agent_config["actor_hiddens"] = agent_config["critic_hiddens"] - elif algorithm == 'TD3': - agent_config["target_noise_clip"] = agent_config["target_noise_clip_relative"] * agent_config["target_noise"] - del agent_config["target_noise_clip_relative"] #hack have to delete it otherwise Ray will crash for unknown config param. - - # else: #if algorithm == 'SAC': - if "state_space_type" in env_config: - if env_config["env_config"]["state_space_type"] == 'continuous': - env_config["env_config"]["action_space_dim"] = env_config["env_config"]["state_space_dim"] - - #hacks end - - eval_config = config.eval_config - - if env_config["env"] in ["HalfCheetahWrapper-v3", "HopperWrapper-v3", "PusherWrapper-v2", "ReacherWrapper-v2"]: - if "time_unit" in env_config["env_config"]: #hack This is needed so that the environment runs the same amount of seconds of simulation, even though episode steps are different. - env_config["horizon"] /= env_config["env_config"]["time_unit"] - env_config["horizon"] = int(env_config["horizon"]) - - agent_config["learning_starts"] /= env_config["env_config"]["time_unit"] - agent_config["learning_starts"] = int(agent_config["learning_starts"]) - - agent_config["timesteps_per_iteration"] /= env_config["env_config"]["time_unit"] - agent_config["timesteps_per_iteration"] = int(agent_config["timesteps_per_iteration"]) - - eval_config["evaluation_config"]["horizon"] /= env_config["env_config"]["time_unit"] - eval_config["evaluation_config"]["horizon"] = int(eval_config["evaluation_config"]["horizon"]) - - agent_config["train_batch_size"] *= env_config["env_config"]["time_unit"] # this is needed because Ray (until version 0.8.6 I think) fixes the ratio of number of samples trained/number of steps sampled in environment - agent_config["train_batch_size"] = int(agent_config["train_batch_size"]) - - extra_config = { - "callbacks": { - # "on_episode_start": tune.function(on_episode_start), - # "on_episode_step": tune.function(on_episode_step), - "on_episode_end": tune.function(on_episode_end), - # "on_sample_end": tune.function(on_sample_end), - "on_train_result": tune.function(on_train_result), - # "on_postprocess_traj": tune.function(on_postprocess_traj), - }, - # "log_level": 'WARN', - } - - # tune_config = reduce(deepmerge, [agent_config, env_config, model_config, eval_config, extra_config]) - tune_config = {**agent_config, **model_config, **env_config, **eval_config, **extra_config} # This works because the dictionaries involved have mutually exclusive sets of keys, otherwise we would need to use a deepmerge! - print("tune_config:",) - pp.pprint(tune_config) - - #hack Common #mujoco wrapper to allow Mujoco envs to be wrapped by MujocoEnvWrapper (which fiddles with lower-level Mujoco stuff) and then by GymEnvWrapper which is more general and basically adds dimensions from MDPP which are common to discrete and continuous environments - if env_config["env"] in ["HalfCheetahWrapper-v3", "HopperWrapper-v3", "PusherWrapper-v2", "ReacherWrapper-v2"]: - def create_gym_env_wrapper_mujoco_wrapper(config, wrapped_mujoco_env): - '''Creates a GymEnvWrapper around a MujocoEnvWrapper - ''' - from mdp_playground.envs.gym_env_wrapper import GymEnvWrapper - me = wrapped_mujoco_env(**config) - gew = GymEnvWrapper(me, **config) ##IMP Had initially thought to put this config in config["GymEnvWrapper"] but because of code below which converts var_env_configs to env_config, it's best to leave those configs as top level configs in the dict! - return gew - - - #default settings for #timesteps_total - if env_config["env"] in ["HalfCheetahWrapper-v3"]: #hack - timesteps_total = 3000000 - - from mdp_playground.envs.mujoco_env_wrapper import get_mujoco_wrapper #hack - from gym.envs.mujoco.half_cheetah_v3 import HalfCheetahEnv - wrapped_mujoco_env = get_mujoco_wrapper(HalfCheetahEnv) - register_env("HalfCheetahWrapper-v3", lambda config: create_gym_env_wrapper_mujoco_wrapper(config, wrapped_mujoco_env)) - - elif env_config["env"] in ["HopperWrapper-v3"]: #hack - timesteps_total = 1000000 - - from mdp_playground.envs.mujoco_env_wrapper import get_mujoco_wrapper #hack - from gym.envs.mujoco.hopper_v3 import HopperEnv - wrapped_mujoco_env = get_mujoco_wrapper(HopperEnv) - register_env("HopperWrapper-v3", lambda config: create_gym_env_wrapper_mujoco_wrapper(config, wrapped_mujoco_env)) - - elif env_config["env"] in ["PusherWrapper-v2"]: #hack - timesteps_total = 500000 - - from mdp_playground.envs.mujoco_env_wrapper import get_mujoco_wrapper #hack - from gym.envs.mujoco.pusher import PusherEnv - wrapped_mujoco_env = get_mujoco_wrapper(PusherEnv) - register_env("PusherWrapper-v2", lambda config: create_gym_env_wrapper_mujoco_wrapper(config, wrapped_mujoco_env)) - - elif env_config["env"] in ["ReacherWrapper-v2"]: #hack - timesteps_total = 500000 - - from mdp_playground.envs.mujoco_env_wrapper import get_mujoco_wrapper #hack - from gym.envs.mujoco.reacher import ReacherEnv - wrapped_mujoco_env = get_mujoco_wrapper(ReacherEnv) - register_env("ReacherWrapper-v2", lambda config: create_gym_env_wrapper_mujoco_wrapper(config, wrapped_mujoco_env)) - - elif env_config["env"] in ["GymEnvWrapper-Atari"]: #hack - if "AtariEnv" in env_config["env_config"]: - timesteps_total = 10_000_000 - - else: - if algorithm == 'DQN': - timesteps_total = 20000 - elif algorithm == 'A3C': #hack - timesteps_total = 150000 - else: #if algorithm == 'DDPG': #hack - timesteps_total = 20000 - - if 'timesteps_total' in dir(config): - timesteps_total = config.timesteps_total - - if env_config["env"] in ["HalfCheetahWrapper-v3", "HopperWrapper-v3", "PusherWrapper-v2", "ReacherWrapper-v2"]: - if "time_unit" in env_config["env_config"]: #hack This is needed so that the environment runs the same amount of seconds of simulation, even though episode steps are different. - timesteps_total /= env_config["env_config"]["time_unit"] - timesteps_total = int(timesteps_total) - - - print("\n\033[1;32m======== Running on environment: " + env_config["env"] + " =========\033[0;0m\n") - print("\n\033[1;32m======== for " + str(timesteps_total) + " steps =========\033[0;0m\n") - - tune.run( - algorithm, - name=algorithm + str(args.exp_name.split('/')[-1]) + '_' + str(args.config_num), ####IMP Name has to be specified otherwise, may lead to clashing for temp file in ~/ray_results/... directory. - stop={ - "timesteps_total": timesteps_total, - }, - config=tune_config, - checkpoint_at_end=args.save_model, - local_dir=args.framework_dir + '/_ray_results', - #return_trials=True # add trials = tune.run( above - ) - - end = time.time() - print("No. of seconds to run:", end - start) - -if __name__ == '__main__': - args = parse_args() - main(args) \ No newline at end of file From 984e06ea29c61147dd7230f74ed11c47a3fe2df2 Mon Sep 17 00:00:00 2001 From: Raghu Rajan Date: Fri, 1 Oct 2021 20:53:35 +0200 Subject: [PATCH 12/22] small change --- experiments/dqn_vanilla_hps.py | 98 ---------------------------------- 1 file changed, 98 deletions(-) delete mode 100644 experiments/dqn_vanilla_hps.py diff --git a/experiments/dqn_vanilla_hps.py b/experiments/dqn_vanilla_hps.py deleted file mode 100644 index c201410..0000000 --- a/experiments/dqn_vanilla_hps.py +++ /dev/null @@ -1,98 +0,0 @@ -num_seeds = 10 -from collections import OrderedDict -var_env_configs = OrderedDict({ - 'state_space_size': [8],#, 10, 12, 14] # [2**i for i in range(1,6)] - 'action_space_size': [8],#2, 4, 8, 16] # [2**i for i in range(1,6)] - 'delay': [0], - 'sequence_length': [1],#i for i in range(1,4)] - 'reward_density': [0.25], # np.linspace(0.0, 1.0, num=5) - 'make_denser': [False], - 'terminal_state_density': [0.25], # np.linspace(0.1, 1.0, num=5) - 'transition_noise': [0],#, 0.01, 0.02, 0.10, 0.25] - 'reward_noise': [0],#, 1, 5, 10, 25] # Std dev. of normal dist. - 'dummy_seed': [i for i in range(num_seeds)], -}) - -var_agent_configs = OrderedDict({ - # normalise obs./reward, atari preprocessing - #'learning_starts' : [10, 200, 500, 1000, 5000, 10000] - #'target_network_update_freq': [1, 2, 4, 8, 16, 32, 64, 128] - 'train_batch_size': [4, 8, 16, 32, 64, 128], -}) - -var_configs = OrderedDict({ - "env": var_env_configs, - "agent": var_agent_configs -}) - -env_config = { - "env": "RLToy-v0", - "horizon": 100, - "env_config": { - 'seed': 0, #seed - 'state_space_type': 'discrete', - 'action_space_type': 'discrete', - 'generate_random_mdp': True, - 'repeats_in_sequences': False, - 'reward_scale': 1.0, - 'completely_connected': True, - }, -} - -algorithm = "DQN" -agent_config = { - "adam_epsilon": 1e-4, - "beta_annealing_fraction": 1.0, - "buffer_size": 1000000, - "double_q": False, - "dueling": False, - "exploration_final_eps": 0.01, - "exploration_fraction": 0.1, - "final_prioritized_replay_beta": 1.0, - "hiddens": None, - "learning_starts": 1000, - "lr": 1e-4, # - "n_step": 1, - "noisy": False, - "num_atoms": 1, - "prioritized_replay": False, - "prioritized_replay_alpha": 0.5, - "sample_batch_size": 4, - #"rollout_fragment_length":4, - "schedule_max_timesteps": 20000, - "target_network_update_freq": 800, - "timesteps_per_iteration": 1000, - "min_iter_time_s": 0, - "train_batch_size": 32, -} - -model_config = { - "model": { - "fcnet_hiddens": [32, 32], - "custom_preprocessor": "ohe", - "custom_options": {}, # extra options to pass to your preprocessor - "fcnet_activation": "tanh", - "use_lstm": False, - "max_seq_len": 20, - "lstm_cell_size": 256, - "lstm_use_prev_action_reward": False, - }, -} - -from ray import tune -eval_config = { - "evaluation_interval": 1, # I think this means every x training_iterations - "evaluation_config": { - "explore": False, - "exploration_fraction": 0, - "exploration_final_eps": 0, - "evaluation_num_episodes": 10, - "horizon": 100, - "env_config": { - "dummy_eval": True, #hack Used to check if we are in evaluation mode or training mode inside Ray callback on_episode_end() to be able to write eval stats - 'transition_noise': 0 if "state_space_type" in env_config["env_config"] and env_config["env_config"]["state_space_type"] == "discrete" else tune.function(lambda a: a.normal(0, 0)), - 'reward_noise': tune.function(lambda a: a.normal(0, 0)), - 'action_loss_weight': 0.0, - } - }, -} From b84d193c926467bbf70b389a477f5aa9ff87bd92 Mon Sep 17 00:00:00 2001 From: Raghu Rajan Date: Fri, 1 Oct 2021 20:56:27 +0200 Subject: [PATCH 13/22] small change --- plot_experiments.ipynb | 414 +++++++++-------------------------------- 1 file changed, 93 insertions(+), 321 deletions(-) diff --git a/plot_experiments.ipynb b/plot_experiments.ipynb index cbee666..f6ae74e 100644 --- a/plot_experiments.ipynb +++ b/plot_experiments.ipynb @@ -2,370 +2,170 @@ "cells": [ { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "#### Setup to analyse an MDP Playground experiment\n", + "# Setup to analyse an MDP Playground experiment\n", "from mdp_playground.analysis import MDPP_Analysis\n", "\n", "# Set the following to True to save PDFs of plots that you generate below\n", - "save_fig = True" + "save_fig = False" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": { - "scrolled": true + "scrolled": false }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Loading data from a sequential run/already combined runs of experiment configurations.\n", - "Training stats read (rows, columns): (40000, 15)\n", - "train stats shape: (1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 10, 3)\n", - "train_aucs.shape: (1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 10, 3)\n", - "eval stats shape: (1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 10, 3)\n", - "eval_aucs.shape: (1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 10, 3)\n", - "Dimension varied: sequence_length . The values it took: ['1', '2', '3', '4'] . Number of values it took: 4 . Index in loaded data: 4\n", - "Loading data from a sequential run/already combined runs of experiment configurations.\n", - "Training stats read (rows, columns): (40000, 15)\n", - "train stats shape: (1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 10, 3)\n", - "train_aucs.shape: (1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 10, 3)\n", - "eval stats shape: (1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 10, 3)\n", - "eval_aucs.shape: (1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 10, 3)\n", - "Dimension varied: sequence_length . The values it took: ['1', '2', '3', '4'] . Number of values it took: 4 . Index in loaded data: 4\n", - "Loading data from a sequential run/already combined runs of experiment configurations.\n", - "Training stats read (rows, columns): (50000, 15)\n", - "train stats shape: (1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 10, 3)\n", - "train_aucs.shape: (1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 10, 3)\n", - "eval stats shape: (1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 10, 3)\n", - "eval_aucs.shape: (1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 10, 3)\n", - "Dimension varied: delay . The values it took: ['0', '1', '2', '4', '8'] . Number of values it took: 5 . Index in loaded data: 3\n", - "Loading data from a sequential run/already combined runs of experiment configurations.\n", - "Training stats read (rows, columns): (50000, 15)\n", - "train stats shape: (1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 10, 3)\n", - "train_aucs.shape: (1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 10, 3)\n", - "eval stats shape: (1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 10, 3)\n", - "eval_aucs.shape: (1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 10, 3)\n", - "Dimension varied: delay . The values it took: ['0', '1', '2', '4', '8'] . Number of values it took: 5 . Index in loaded data: 3\n" - ] - } - ], + "outputs": [], "source": [ "# Data loading\n", "mdpp_analysis = MDPP_Analysis()\n", "\n", - "# Load experiments' data.\n", + "# Also load evaluation runs, which may be run intermittently during training runs\n", + "load_eval = False\n", + "\n", + "# load multiple experiments data\n", "\n", "# experiments = { : , ... }\n", "# For each experiment (also works in case of a single experiment):\n", - "# Set exp_name to the name that was given to the experiment when running it, i.e., with the -e option\n", "# Set dir_name to the location where the CSV files from running an experiment were saved\n", - "files_dir = \"/mnt/484A4CAB4A4C9798/GoogleDrive/Maestria-Drive/HiWi/mdp_files/baselines\"\n", + "# Set exp_name to the name that was given to the experiment when running it, i.e., with the -e option\n", "experiments = {\n", - " \"a3c_seq\" : \"%s/a3c_seq/\"%files_dir,\n", - " \"a3c_lstm_seq\" : \"%s/a3c_lstm_seq/\"%files_dir,\n", - " \"a3c_del\" : \"%s/a3c_del/\"%files_dir,\n", - " \"a3c_lstm_del\" : \"%s/a3c_lstm_del/\"%files_dir,\n", + " \"td3_move_to_a_point_p_noise_target_radius\": \"/home/rajanr/spider_plots_data_Suresh/mdpp_12707717_TD3_P_noise_target_radius\",\n", + " \"ddpg_move_to_a_point_p_noise\": \"/home/rajanr/spider_plots_data_Suresh/mdpp_12680567_DDPG_P_noise\",\n", + " \"ddpg_move_to_a_point_r_noise\": \"/home/rajanr/spider_plots_data_Suresh/mdpp_12700125_DDPG_R_Noise\",\n", + " \"ddpg_move_to_a_point_target_radius\": \"/home/rajanr/spider_plots_data_Suresh/mdpp_12702414_DDPG_target_radius\",\n", + " \"ddpg_move_to_a_point_action_max\": \"/home/rajanr/spider_plots_data_Suresh/mdpp_12703211_DDPG_action_max\",\n", + " \"ddpg_move_to_a_point_time_unit\": \"/home/rajanr/spider_plots_data_Suresh/mdpp_12703537_DDPG_time_unit\",\n", + " \"ddpg_move_to_a_point_action_loss_weight\": \"/home/rajanr/spider_plots_data_Suresh/mdpp_12705480_DDPG_action_loss_weight\",\n", + " \"ddpg_move_to_a_point_irr_dims\": \"/home/rajanr/spider_plots_data_Suresh/mdpp_12713180_DDPG_irrelevant_features\",\n", + " \"td3_move_to_a_point_r_noise\": \"/home/rajanr/spider_plots_data_Suresh/mdpp_12712031_TD3_R_noise\",\n", + " \"td3_move_to_a_point_action_max\": \"/home/rajanr/spider_plots_data_Suresh/mdpp_12713006_TD3_action_max\",\n", + " \"td3_move_to_a_point_time_unit\": \"/home/rajanr/spider_plots_data_Suresh/mdpp_12713385_TD3_time_unit\",\n", + " \"td3_move_to_a_point_action_loss_weight\": \"/home/rajanr/spider_plots_data_Suresh/mdpp_12720811_TD3_action_loss_weight\",\n", + " \"td3_move_to_a_point_irr_dims\": \"/home/rajanr/spider_plots_data_Suresh/mdpp_12721705_TD3_irrelevant_features\",\n", + " \"sac_move_to_a_point_p_noise_target_radius\": \"/home/rajanr/spider_plots_data_Suresh/mdpp_12762946_SAC_P_noise_target_radius\",\n", + " \"sac_move_to_a_point_r_noise\": \"/home/rajanr/spider_plots_data_Suresh/mdpp_12760692_SAC_R_Noise\",\n", + " \"sac_move_to_a_point_action_max\": \"/home/rajanr/spider_plots_data_Suresh/mdpp_12746746_SAC_action_space_max\",\n", + " \"sac_move_to_a_point_time_unit\": \"/home/rajanr/spider_plots_data_Suresh/mdpp_12747791_SAC_time_unit\",\n", + " \"sac_move_to_a_point_action_loss_weight\": \"/home/rajanr/spider_plots_data_Suresh/mdpp_13090055_SAC_action_loss_weight\",\n", + " \"sac_move_to_a_point_irr_dims\": \"/home/rajanr/spider_plots_data_Suresh/mdpp_12748228_SAC_irrelevant_features\", \n", "}\n", "\n", "# Remember to set load_eval=False in case evaluation stats were not recorded and only training stats were recorded, otherwise there will be errors in loading the data in this cell.\n", - "list_exp_data = mdpp_analysis.load_data(experiments, load_eval=True)" + "list_exp_data = mdpp_analysis.load_data(experiments, load_eval=load_eval, exp_type='grid')" ] }, { "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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/3j233//h37XbrrppjzxiU98WGmbDN3B+8lPfjLLli3Lk570pCRDv6vXXHNNrrnmmofWrVy5Mttuu+06565atSrPfvazM2PGjFx11VUPjT//+c/PNddck+uuuy4zZsx4aHyPPfbIzJkz11m7Phv7b5kkVXVZa23BRi8GAAAAAABj5I5gAPrq/PPPz+Me97i8+tWvXmf87W9/+8PWnnvuuVmzZk2OPvro3Hbbbet8HXLIIXnwwQdz4YUXbvD9hpfAq1atyu9///usWrUqBx54YJYuXZq77777oflFixblpptuygUXXPDQ2I9//OMsW7YsRx999ER/ZAAAAAAAmHIz+x2AiVjc7wCbbLrczdjPHJt6V/V0+AwH+fNj+rj66quz7777rnPHbZLsvPPO2WGHHdYZW7p0aZLkRS960Xqvt3z58g2+3y233JJ3vetd+cY3vpFbbrnlYfN33nlntttuuyTJK17xihx//PE544wzcsghhyRJzjjjjGy99dYPK64BAAAAAGA6UQQDMDDWPs7g7LPPzs477zzqmrXbQq/v/IMPPjhLly7NG9/4xixYsCDbb799ZsyYkS984Qs555xz8uCDDz60fptttsnhhx+e0047LcuXL88222yTc889Ny9+8Yszb968yf3hAAAAAABgEimC2UIt7neAAbe43wHokCc96UlZtmxZHnjggXXuCr7pppty5513rrP2KU95SpJk7ty5G7wreH1+8Ytf5Oc//3lOPPHEvOc971ln7vOf//yo5yxatCif+tSnctZZZ2X77bfPqlWrbAsNAAAAAMC05xnBAPTVS17ykixfvjxnn332OuMf+MAHHrb20EMPzaxZs3LSSSflnnvuedj8XXfdlTVr1qz3vdYWzW3E3uK//OUvc9555416zt57753nPOc5OfPMM3PGGWdk1113zcEHH7zRnwsAAAAAAPrJHcEA9NXb3va2nHPOOTn22GNz2WWX5elPf3oWL16cSy65JHPnzl1n7S677JLPfOYzOeaYY7LXXnvliCOOyG677ZZbb701V155Zc4///xcddVVmT9//qjvtddee+XpT396PvjBD2bVqlXZc8898+///u857bTT8sxnPjOXXXbZqOctWrQoxxxzTJLkpJNOylZb+XdUAAAAAABMb4pgAPpqxx13zEUXXZQ3v/nND90VvP/+++eHP/xhDjro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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "execution_count": null, + "metadata": { + "scrolled": false + }, + "outputs": [], "source": [ "# 1-D: Plots showing reward after 20k timesteps when varying a single meta-feature\n", - "# Plots across 10 runs: Training: with std dev across the runs\n", - "mdpp_analysis.plot_1d_dimensions(list_exp_data, save_fig, plot_type = \"agent\")" + "# Plots across runs: Training: with std dev across the runs\n", + "mdpp_analysis.plot_1d_dimensions(list_exp_data, save_fig, plot_type = \"agent\")\n", + "mdpp_analysis.plot_1d_dimensions(list_exp_data, save_fig, use_aucs=True, plot_type = \"agent\")" ] }, { "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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Dp/4xCeyxx57jDtm4xHXE80/4ogjsmbNmrz61a/OyMhIFi9enAULFuTjH/94zj333Nx33333j99xxx1z1FFH5Ywzzsi6deuy44475vzzz88f/dEfZenSpf394QAAAAAAoI+EyQAMvUc+8pG58sorc++9926yO/n666/PrbfeusnYxzzmMUmSJUuWbHZ38kR+8IMf5Pvf/35OPvnkvO1tb9uk72Mf+9i4c1asWJEPfehDOeecc7J48eKsX7/eEdcAAAAAAGz1vDMZgKH33Oc+N+vWrcsnPvGJTdrf9a539Yw98sgjs8MOO+Stb31r7rzzzp7+X/7yl9mwYcOE99oYVm/c4bzRD3/4w1xwwQXjzjnggANy8MEH5+yzz85ZZ52VvfbaK0ccccQWfy4AAAAAABgkO5MBGHpveMMbcu655+blL395Vq9encc97nFZuXJlvvWtb2XJkiWbjH34wx+ev//7v8/xxx+f/fffP0cffXT23nvv3Hjjjbn88svzuc99LldccUWWLVs27r3233//PO5xj8u73/3urF+/Pvvuu2/+/d//PWeccUae8IQnZPXq1ePOW7FiRY4//vgkyVvf+tZst52/5wIAAAAAYOsmTAZg6O2222659NJL89rXvvb+3cmHHnpoLr744hx++OE944899tjss88+ec973pMzzjgjt956a5YsWZJ99903p556ah760IdOeK8FCxbkS1/6Ul73utflnHPOyR133JHHP/7xOeecc/L9739/wjD5RS96UV772tfm9ttvz7HHHtufHxwAAAAAAGZRjT2mk80bGRlpq1atGnQZfbF8+fIkycqVKwdaBwyrqkFXsGVf+cqaLFmy/6ysPTIyK8tuszZs2JA99tgjBx10UP7pn/5pSnPXrFmT/fff/L9jVa1urflXAQAAAACgb5yxCQBz4FOf+lR+8YtfZMWKFYMuBQAAAAAAJsUx1wAwi774xS/m6quvzimnnJLHPvax+eM//uNBlwQAAAAAAJMiTAaAWXTCCSfkuuuuy4EHHpiPfexjWbBgwaBLAgAAAACASREmD9jW8M7VQdYwzK/s9s7pmfH8mC/Wrl076BIAAAAAAGBavDMZAAAAAAAAgB52JsM8Zmf84O4NAAAAAACwtRMmM9SEoYO7NwAAAAAAANs2YfK8tnLQBQCz7L77kqQl2Qr+8oJpaf5qBAAA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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "execution_count": null, + "metadata": { + "scrolled": false + }, + "outputs": [], "source": [ - "# Plots across 10 runs: Evaluation: with std dev across the runs\n", - "mdpp_analysis.plot_1d_dimensions(list_exp_data, save_fig, train=False, plot_type = \"agent\")" + "# Plots across runs: Evaluation: with std dev across the runs\n", + "if load_eval:\n", + " mdpp_analysis.plot_1d_dimensions(list_exp_data, save_fig, train=False, plot_type = \"agent\")\n", + " mdpp_analysis.plot_1d_dimensions(list_exp_data, save_fig, train=False, use_aucs=True, plot_type = \"agent\")" ] }, { "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "ename": "AttributeError", - "evalue": "'list' object has no attribute 'replace'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# 1-D: Plots showing reward after 20k timesteps when varying a single meta-feature\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;31m# Plots across 10 runs: Training: with std dev across the runs\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mmdpp_analysis\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplot_1d_dimensions\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlist_exp_data\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msave_fig\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mplot_type\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m\"metric\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;32m/mnt/484A4CAB4A4C9798/GoogleDrive/Maestria-Drive/HiWi/mdp-playground/mdp_playground/analysis/analysis.py\u001b[0m in \u001b[0;36mplot_1d_dimensions\u001b[0;34m(self, list_exp_data, save_fig, train, metric_num, plot_type)\u001b[0m\n\u001b[1;32m 460\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;34m'_train'\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mtrain\u001b[0m \u001b[0;32melse\u001b[0m \u001b[0;34m'_eval'\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m'_final_reward_'\u001b[0m \u001b[0;34m+\u001b[0m\u001b[0;31m \u001b[0m\u001b[0;31m\\\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 461\u001b[0m \u001b[0mstats_data\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mgroup_key\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0msub_group_key\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'axis_labels'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreplace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m' '\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m'_'\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m\u001b[0;31m \u001b[0m\u001b[0;31m\\\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 462\u001b[0;31m \u001b[0;34m'_'\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstats_data\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mgroup_key\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0msub_group_key\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'metric_names'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mmetric_num\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m'_1d.pdf'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 463\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msavefig\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfig_name\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdpi\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m300\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbbox_inches\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"tight\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 464\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mAttributeError\u001b[0m: 'list' object has no attribute 'replace'" - ] - }, - { - "data": { - "image/png": "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DLoAANgUp59+eg499NAcfvjhOeGEE3LNNdfkoQ996H39CxYsyGWXXZYDDzxwnXkvetGL8pjHPCave93rsmLFivvab7zxxjznOc/J6tWrc8EFF+RJT3rSOvPe/OY357zzzsutt946rZ8LAAAAAAA2hRXBAAytSy+9NJdffnmOPvrovPCFL8ycOXPutyr4wQ9+8P1C4CTZb7/9sv/+++cHP/jBOu3vfOc786tf/SrveMc77hcCr/Wnf/qnOeKII6bscwAAAAAAwFQTBDMrLV68OIsXLx50GUPL98dMcfrpp2e77bbLkiVLMn/+/Dz72c/ORz/60axZs2ajc9esWZNf/vKX2WWXXdZp/+xnP5utttoqRx999HSVDQAAAAAA004QDMBQWr16dc4666wsWbIk2267bZLk6KOPznXXXZfzzjtvo/NPOeWU/PKXv1wn8L399ttz7bXXZt999828efOmrXYAAAAAAJhugmAAhtI555yT3/zmN+sEuc985jOzYMGC+20PPdry5cvz2te+No9+9KPz93//9/e133bbbUmSHXbYYXqKBgAAAACAzWTOoAtgMs4fdAGbrGrQFfQMso7WNm3+TPgOh/n7Y/idfvrpWbBgQRYuXJirr776vvZnPOMZOfvss7Ny5crMnz//fvMuueSSPOtZz8puu+2WL33pS5k7d+59fWsD4Ntvv336PwAAAAAAAEwjQTAAQ+enP/1pli1bltZa9tlnnzHHfPzjH88JJ5ywTtull16aww47LDvuuGOWLVuW3XfffZ3+7bffPnvuuWeuuuqqrFq1yvbQAAAAAAAMLUEws9T5gy5gyJ0/6AKY5T784Q+ntZbTTjstO+200/363/SmN+WMM85YJwi+9NJL8/SnPz3bb799li1blj333HPMZz//+c/Pe97znpx55pk57rjjpukTAAAAAADA9BIEAzBU1qxZk4985CM54IADcuyxx4455oorrsjSpUtz8cUX56CDDspll12Www47LNttt12WLVuWvffee73Pf/3rX5+Pf/zjef3rX58DDjgghxxyyP3GfO1rX8stt9ySI444Yso+FwAAAAAATCVBMABD5Wtf+1p+8Ytf5JhjjlnvmCVLlmTp0qU5/fTTs/POO+ewww7Lrbfemle/+tVZvnx5li9fvs745z3vedl2222TJLvuumv+7d/+LYcffnie9KQn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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "execution_count": null, + "metadata": { + "scrolled": false + }, + "outputs": [], "source": [ "# 1-D: Plots showing reward after 20k timesteps when varying a single meta-feature\n", - "# Plots across 10 runs: Training: with std dev across the runs\n", - "mdpp_analysis.plot_1d_dimensions(list_exp_data, save_fig, plot_type = \"metric\")" + "# Plots across runs: Training: with std dev across the runs\n", + "mdpp_analysis.plot_1d_dimensions(list_exp_data, save_fig, plot_type = \"metric\")\n", + "mdpp_analysis.plot_1d_dimensions(list_exp_data, save_fig, use_aucs=True, plot_type = \"metric\")" ] }, { "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "ename": "AttributeError", - "evalue": "'list' object has no attribute 'replace'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# Plots across 10 runs: Evaluation: with std dev across the runs\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mmdpp_analysis\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplot_1d_dimensions\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlist_exp_data\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msave_fig\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtrain\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mplot_type\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m\"metric\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;32m/mnt/484A4CAB4A4C9798/GoogleDrive/Maestria-Drive/HiWi/mdp-playground/mdp_playground/analysis/analysis.py\u001b[0m in \u001b[0;36mplot_1d_dimensions\u001b[0;34m(self, list_exp_data, save_fig, train, metric_num, plot_type)\u001b[0m\n\u001b[1;32m 460\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;34m'_train'\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mtrain\u001b[0m \u001b[0;32melse\u001b[0m \u001b[0;34m'_eval'\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m'_final_reward_'\u001b[0m \u001b[0;34m+\u001b[0m\u001b[0;31m \u001b[0m\u001b[0;31m\\\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 461\u001b[0m \u001b[0mstats_data\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mgroup_key\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0msub_group_key\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'axis_labels'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreplace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m' '\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m'_'\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m\u001b[0;31m \u001b[0m\u001b[0;31m\\\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 462\u001b[0;31m \u001b[0;34m'_'\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstats_data\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mgroup_key\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0msub_group_key\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'metric_names'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mmetric_num\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m'_1d.pdf'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 463\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msavefig\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfig_name\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdpi\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m300\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbbox_inches\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"tight\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 464\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mAttributeError\u001b[0m: 'list' object has no attribute 'replace'" - ] - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAB5MAAAFACAYAAACRA1ujAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAtYklEQVR4nO3deZRlVX0v8O8PWugGBBQaFIgMKgJBRS0QlSioGONEtJ954BBUDCZRFE00S0Vsh8TlM1FfcCAgKAFRHxGjOGPsxgF90CAOiD4NgwIyNsrUjWDv98e9rUXd6u4abtWt2/X5rHXXqbPP3vv87umCf76196nWWgAAAAAAAABgtE0GXQAAAAAAAAAAc48wGQAAAAAAAIAewmQAAAAAAAAAegiTAQAAAAAAAOghTAYAAAAAAACghzAZAAAAAAAAgB7CZIBZUlVtzOfgPs69dMzcy/s1NwAAAAAAMD8JkwEAAAAAAADoIUwGAAAAAAAAoIcwGQAAAAAAAIAewmQAAAAAAAAAegiTAfqkqhZW1XFVdVlVraqq66rqE1W17yTm2LGqllbV+VV1U1X9tqpurKplVXVMVS2cYm2bVdWRVfXBqvpOVV1RVb+pqruramVVXVRV/7uq9hkz7hVV1UZ9vruO+e/fnWttvzVVtftUagUAAAAAAOaGaq0NugaAoVdV2yT5WpKRcS7fleT5ST43pv2Q1tryUXO8KMm/JdliPbf6eZLntNYuG3P/pUneOqrpvNbawaOuPyDJrzb0PZLck+Q1rbUPdcdtleSaJFuP6rPPOPd/aZJTRzV9o7X2pAncDwAAAAAAmKOsTAboj5MyfpCcJJsn+eT6BlfV85P8e9YfJCfJQ5Kc2w2HZ8KCJCdU1aOTpLV2e5LTx/R56Tjjlow5//cZqA0AAAAAAJhFwmSAaeoGr38xpvn7SZ6R5NHprBhe5/bU3dW/H0pSo5o/neTJSfZK8uzufGvtnOQfJ1lmS3Jpd9xhSQ5Msme3vpcluWpU302SvGrU+YfGzPXiqlowqv6tkxw66vqqJGdNsj4AAAAAAGCOWbDhLgBswBFjzlcleWpr7abu+feq6r5J/n4d45ck2X7U+XeSPL/94T0EP62qHyf571F9XlRVx7TW7pxIga2165Os693N36uq36QTYK/1hFFjf1xV5yVZu231A5L8WZJzuufPSrLZqLGfaa3dOpG6AAAAAACAucvKZIDp23/M+ZdGBclrrW/b5z8Zc/64JGuqqq395N5BctIJb8fed72qapuq+ruqOreqrq6qO0fN/+kx3Xcac/7hMeejt7q2xTUAAAAAAGyErEwGmL4dx5xfOU6fq8ZpW2tscDtRE35vclXtm+TcSYzZasz52UmuGzX+WVW1OMkdSZ4+qt+1Sb420boAAAAAAIC5y8pkgOmrDXdJ23CXSVs0ib6nZRLh81ittbuTfGRU032SvCid7a63GNV+Rmvtd1O9DwAAAAAAMHdYmQwwfdcnedio813H6bPbesZfN+b8P5O8dgL3HbuV9riqavckjx7T/KkkH0xnJfHv0nkf8sc2MNW/JXljkk275y9N8qMxfWxxDQAAAAAAGwkrkwGm78Ix539WVduNaXvxesZ/c8z5E5Pc01q7crxPktuSPKq1dvsE63vgOG1/3Vr7Zmvtv7tzPnJDk7TWrk5yzqimhyf5H6POL2qtXTrBmgAAAAAAgDlOmAwwfZ8Yc75FknOr6ulVtV9VHZfkdesZ/x9Jbh51fv8k36iqV1TVY6pqz6p6QlX9TVX9Z5Krk7xmEvWNt4L5H6vqEVU1UlX/axLzfXjM+X1G/WxVMgAAAAAAbESqtZl4jSfA/FJVZ+Xeq3THuie9rxY4pLW2vDv+8PSG0utzXmvt4FH3X5rkreu5/pPceyvusa5PsuPohtZaz7ugq6qS/DTJQ8dcujvJTq21CW29DQAAAAAAzH1WJgP0x18luXgd136X5Kj1DW6tfTKdrbAnunX11RMvLUlydJLV67j2/5IcM5FJWucvkE4c59IXBckAAAAAALBxESYD9EFr7ddJDkpndfBPk9yVzvbSn03yhNbaBreAbq2dkWSPJG9Ocl6SG9NZ8bsqyVVJvtS99ojW2osmWd83kjw2ydlJVnbr++8k70myf/deE/XRbk2j2eIaAAAAAAA2Mra5BmBSqmqTJFcm+aNu08okD2yt/XZgRQEAAAAAAH1nZTIAE9Z9Z/Kr84cgOUk+JkgGAAAAAICNj5XJAGxQVb06nRD5/knuN+rSqiQPba1dM5DCAAAAAACAGbNg0AUAMBTun+TB47S/RpAMAAAAAAAbJ9tcAzBZNydZluRprbWTB10MAAAAAAAwM2xzDQAAAAAAAEAPK5MBAAAAAAAA6CFMBgAAAAAAAKCHMBkAAAAAAACAHsJkAAAAAAAAAHoIkwEAAAAAAADoIUwGAAAAAAAAoIcwGQAAAAAAAIAewmQAAAAAAAAAegiTAQAAAAAAAOghTAYAAAAAAACghzAZAAAAAAAAgB7CZAAAAAAAAAB6CJMBAAAAAAAA6CFMBgAAAAAAAKCHMBkAAAAAAACAHsJkAAAAAAAAAHoIkwEAAAAAAADoIUwGAAAAAAAAoIcwGQAAAAAAAIAewmQAAAAAAAAAegiTAQAAAAAAAOghTAYAAAAAAACghzAZAAAAAAAAgB4DDZOr6o1VdVZVXV5VraquXEe/hVX1V1X12aq6sqpWdcd8oqr2nsT9XtK9z3ifD/TtiwEAAAAAAAAMuQUDvv8/JVmZ5OIk266n325JTkryrSSnJLk2yR5J/ibJ86rq6a21ZZO872Vj2n46ifEAAAAAAAAAG7VBh8kPbq1dniRV9aMkW62j341JHtVau2R0Y1V9PMn3krwnycgk7ntua235pKsFAAAAAAAAmCcGGiavDZIn0O/mJDeP0/7jbgi972TvXVX3TXJXa+23kx0LAAAAAAAAsLEb6DuTp6uqNknywCTXT3Lo55LcmmR1VX2/ql7U9+IAAAAAAAAAhtigt7merr9OJ0x+xwT735nkzCRfT3JDkt2TvDLJ6VX14Nba22akSgAAAAAAAIAhU621QdeQ5A/vTG6t7TbB/o9PJxT+SZIDW2urp3jfzZOsSLJXkoe21q4cp8/RSY5Oki233PIxe+2111RuBQAz5qKLLrqptbZ40HUAAAAAALDxGMowuaoek+RrSW5J8iettWumee8jk3wsyStaayetr+/IyEhbsWLFdG4HAH1XVRe11kYGXQcAAAAAABuPoXtnclU9Osm5SX6T5JDpBsldV3aP2/dhLgAAAAAAAIChN1RhcjdI/lqS29IJkq/q09QP7R6v79N8AAAAAAAAAENtaMLkqnpUOiuSb08nSL5iPX23qKq9quqBY9q3G6fvNkn+Iclvk3ylv1UDAAAAAAAADKcFg7x5Vb04ya7d08VJNquq47rnV7XWTu/22zWdIPl+Sf41yeOr6vFjpvtMa+2O7s8HJFmW5LQkLxnV54dVdV6SHya5IcluSV6W5IFJ/q61dnX/vh0AAAAAAADA8BpomJzkqCRPGtP2ju7xvCSnd3/ePcnaVcVL1zHX7knuWMe1tT6R5OAkT0uydTrvXb4gyUtba1YlAwAAAAAAAHQNNExurR08wX7Lk9Qk5h23f2vt7yY6BwAAAAAAAMB8NjTvTAYAAAAAAABg9gx6m2sA5qBbb701N9xwQ+6+++5BlzJvLViwIAsXLszixYuzcOHCQZcDAAAAAMA8JEwG4F5uvfXWXH/99dl5552zaNGiVE34LQP0SWst99xzT26//fb84he/yI477phtttlm0GUBAAAAADDPCJMBhtDBBx+cJFm+fHnf577hhhuy8847Z4sttuj73ExMVeU+97lP7ne/+2XzzTfPddddJ0wGAAAAAGDWeWcyAPdy9913Z9GiRYMug65FixblrrvuGnQZAAAAAADMQ8JkAHrY2nru8G8BAAAAAMCgCJMBAAAAAAAA6CFMBgAAAAAAAKCHMBkAAAAAAACAHsJkgCmqGtznvPM6n5mY+6qrkhUrxv8M8juP9+mXW265JYsWLUpV5fTTT++5vnr16px88sk57LDDsttuu2XRokXZY489csQRR+Syyy5b77xvf/vbs//++2fbbbfNZpttll122SVLlizJ2WefndZa/74EAAAAAAD0mTAZgHnv4x//eO66667svvvuOfXUU3uuX3nllTn66KOzcuXKHHXUUfnABz6QI444Il/5yley3377ZdmyZT1jLrjgguyzzz5529vell122SVLly7NiSeemFe84hW59tprs2TJknz4wx+eja8HAAAAAABTsmDQBQDAoJ1yyik55JBDcthhh+XYY4/N5Zdfnj322OP31xcvXpzvfe972W+//e417oUvfGEe9ahH5fWvf31WrFjx+/brrrsuz372s7N69eqcd955Oeigg+417i1veUu+8pWv5JZbbpnR7wUAAAAAANNhZTIA89rFF1+cSy65JEceeWRe8IIXZMGCBT2rk7fbbrueIDlJ9tlnn+y777750Y9+dK/297znPbnhhhvy7ne/uydIXutP//RPc/jhh/ftewAAAAAAQL8JkwGY10455ZRstdVWWbJkSbbffvs861nPymmnnZY1a9ZscOyaNWvyq1/9KjvuuOO92j/96U9ns802y5FHHjlTZQMAAAAAwIwTJgMMpeXdD9OxevXqnHnmmVmyZEm23HLLJMmRRx6Zq6++Ol/5ylc2OP7EE0/Mr371q3uFxrfddluuuuqqPOxhD8uiRYtmrHYAAAAAAJhpwmQA5q2zzz47v/71r+8VBj/jGc/I4sWLe7a6Huv888/P6173ujzykY/Mm970pt+333rrrUmSrbfeemaKBgAAAACAWbJg0AUAwKCccsopWbx4cXbZZZf8/Oc//3370572tJx11lm56aabsv322/eMu+iii/LMZz4zO+20U77whS9k4cKFv7+2NkS+7bbbZv4LAAAAAADADBImAzAvXXHFFVm2bFlaa9lzzz3H7XPGGWfk2GOPvVfbxRdfnEMPPTTbbLNNli1blp133vle1+973/tm1113zU9+8pOsWrXKVtcAAAAAAAwtYTIA89JHP/rRtNZy8sknZ9ttt+25ftxxx+XUU0+9V5h88cUX56lPfWrue9/7ZtmyZdl1113Hnft5z3te3ve+9+X000/P0UcfPUPfAAAAAAAAZpYwGYB5Z82aNfnYxz6Whz/84Xn5y18+bp9LL700S5cuzYUXXpj9998/3/ve93LooYdmq622yrJly7L77ruvc/43vOENOeOMM/KGN7whD3/4w/O4xz2up89Xv/rVrFy5MocffnjfvhcAAAAAAPSTMBmAeeerX/1qfvnLX+aoo45aZ58lS5Zk6dKlOeWUU7LDDjvk0EMPzS233JJXv/rVOf/883P++effq/9zn/vcbLnllkmSBzzgAfn85z+fww47LAcddFD+/M//PE984hOz9dZb59prr82Xv/zlfOtb38qHP/zhGf2eAAAAAAAwHcJkAOadU045JUlnO+p12XfffbPnnnvmk5/8ZA477LDcfPPNSZKlS5eO2/+KK674fZicJAcccEAuvfTSnHDCCTnnnHNy/PHHZ9WqVdlhhx1y4IEH5rOf/Wye85zn9O9LAQAAAABAn1VrbdA1DJWRkZG2YsWKQZfRFwcffHCSZPny5QOtA4ZV1aArmBlf+tJl2X77vTfYb2RkFoohSXLZZZdl773X/29SVRe11vyrAAAAAADQN5sMugAAAAAAAAAA5h5hMgAAAAAAAAA9hMkAAAAAAAAA9Fgw6ALmu7nwztVB1jDMr+z2zunp8fwAAAAAAADmNiuTAQAAAAAAAOhhZTLMY1bGD+7eAAAAAAAAc50wmaEmDB3cvQEAAAAAANi4CZPnteWDLgCYg9asSZKWZA78tQZp/moEAAAAAIABESYDA7J80AWwDjfffJ/ssMOqJFsMuhSSrFq1KptvvvmgywAA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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "execution_count": null, + "metadata": { + "scrolled": false + }, + "outputs": [], "source": [ - "# Plots across 10 runs: Evaluation: with std dev across the runs\n", - "mdpp_analysis.plot_1d_dimensions(list_exp_data, save_fig, train=False, plot_type = \"metric\")" + "# Plots across runs: Evaluation: with std dev across the runs\n", + "if load_eval:\n", + " mdpp_analysis.plot_1d_dimensions(list_exp_data, save_fig, train=False, plot_type = \"metric\")\n", + " mdpp_analysis.plot_1d_dimensions(list_exp_data, save_fig, use_aucs=True, train=False, plot_type = \"metric\")" ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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93xNkmTvvd+Yo49+S/7jPz62wtjFi6/J0Ue/KXvs8dIceeT/hrZ77/3GHHXUm3PKKR/NXnu9Idts85CVXu+1r/2nHHzwh1Zoe+lL35RXvOIvc9JJR+bZz355kuShD31MHvvYnXLWWSfnDW84MjNnzvzz+JNOOik77LBDnvKUp0z6+wMAAAAAwNpgRTAwAefFilb65bvf/XLue98H5HnP23eF9le96h33GPvtb38py5bdnj33fG1uumnxCq+nP/35ufvuu3PRRd9a5fU23PDef36/dOmtuemmP2Tp0luz447PzG9+c1mWLLn5z/0vetEBWbz4mnz/+1/7c9uPf/y9XHHFFXnta1870a8MAAAAAABrnRXBDIwVrYO7NkwlV1316zzqUTuusOI2SbbYYqvc5z6brdD2m99cliQ56KDdVjrfDTdct8rr3XDD9fmXf/mnfO97X8kNN1x/j/4lS27KxhtvkiTZffe/y0c/+paceeans/POz0+SnHnmp7PBBhtk3333vce5AAAAAAAwVQiCAZhGRn6D4n3v+2zud7+txh0xb97Kt4VureXgg/fIlVdelpe+9M3ZYYf52XjjTTNjxsx89aufyTnnnJK77777z+PnzNkwz3nOPjn99H/NH/5wXWbP3jDf/vaXsueee2bu3Ln9/WoAAAAAANBHguBp67xBFzDNnTfoAoCeefMekoULr8hdd921wqrgxYuvyS233LTC2Ac+8GFJkk033SJPetLKVwWvzBVX/L9cccVPsv/+h+fAA9+3Qt9XvvKpcc950YsOyGmn/XPOOuvkbLzxplm69FbbQgMAAAAAMOV5RjAAA7Xzzi/IDTdcl7PO+uwK7Sef/H/uMXa33V6SDTaYnRNOeE+WLr3tHv1Llvwxy5bdvtJrzZgxEjS3MXuz//KX/5Pzzjtj3HMe9rDH5dGPfmLOPPOkfOUrn86WWz4oe+yxx2q/FwAAAAAADJIVwQAM1L77HpZzzjklH/zg63L55RfnIQ95dC6++LxceukPstlmW6ww9gEP2CbveMe/5AMf2D8veckOec5zXpmttto2N964KL/61aU577wv59RTf5att95u3Gs9+ME75CEPeXQ+97mPZOnSW7Ptto/IwoW/yBln/Gse+tDH5rLLLh73vBe96IAceeT+SZLXve49mTHD71EBAAAAADC1CYIBGKhNNtk8J554fo455u/zta+NrAr+y798Rj75yXPzxjc+6x7j99zzNdl224fn3//9qJxxxr/mlltuymabbZFtt31EXv/69+d+99typdeaOXNmjj32rHzsY2/LWWednNtu+1O23/4xec97Ts4VV/xkpUHwHnu8NMcc8/e57bYlef7zX9OfLw4AAAAAAGtRjd0ec5jNnz+/LViwoC9zVfVlmmltsj866/s9dP8mZ324f1//+mXZYosd1src8+dP7vw+/VM6bSxbdnue85yt8qhH7Zjjjjun0/277LLLssMOq/5zrKqLW2uT/FMBAAAAAID/ZW9LAFiNs8/+fG6++ca86EUHDLoUAAAAAABYIwMPgqtq46r6x6q6tKpuqarFVXVBVb26asU1e1X1pKr6Vm/czVV1dlU9fkClAzDkvve9r+bUUz+Rj3/8sDz4wY/KM57xwkGXBAAAAAAAa2TCzwiuqo2S3C/JPTZYba0tXMM5ZiT5epKnJDk5yXFJNkrysiSfSbJDknf0xj45yXlJrkpyeG+Kg5OcX1VPaa1dOtHvAgDjOeqoQ7Jo0dXZYYcn5F3v+lRmzpw56JIAAAAAAGCNdAqCe8HtYUkOSbLlKoau6f8pf1KSpyU5trV26KjrHJ/k8iQHphcEJ/l4kmVJdm6tXdUbd2qSy5IcnWSPNf8mALB6Z5555aBLAAAAAACACem6IvjDSd6W5KdJ/jPJHyZ5/U16x6tHN7bWllXV4iSzk6SqHppkxyQnLQ+Be+OuqqrTkrymqrZsrV07yXoAAAAAAAAApr2uQfA+Sc5urT23T9e/KMlNSQ6rqiuT/DAjW0O/KskTkry+N27H3vEH48xxYZL9euPP6lNdAAAAAAAAANNW1yB48yRf6dfFW2s3VtWeST6V5NRRXbck2au19uXe5617x6tyT8vb5vWrLgAAAAAAAIDpbEbH8Zcm2arPNSxJ8j9Jjkry4iT7J/llklOqavfemI16x9vHOX/pmDErqKoDqmpBVS1YtGhR/6oGWMvuvjtJ2qDLYBJa8+cHAAAAAMBgdA2C35fk9VX1wH5cvKoem+SCJN9srb29tXZGa+3TSZ6W5NokJ1bVzCS39k6ZPc40c3rHW8fpS2vthNba/Nba/Llz5/ajbIB14g9/uFeS2wZdBpNw2223Zfbs8f7TBQAAAAAAa1fXraGfkOS3SX5WVWck+U2Su8aMaa2196/hfIdmJMg9bcwEt1bVWUkOTrJdkqt7XeNt/7y8bbxtowGmreOPv38OP/yqzJ07L8mGSWrQJbEGWmu58847c8stt2Tx4sV5wAMeMOiSAAAAAABYD3UNgt876v0+KxnTkqxpELw8xJ05Tt+sUccf9d7vlJHnCY/25N41L17DawJMCxdeuEmOOCJ54xuvzv3ud0dmdN3DYRUuu2xy5y9e3J86pqvV3b9Zs2Zlzpw5edCDHpQ5c+asejAAAAAAAKwFXYPgB/f5+j9LskeSVyf5yPLGqtosyQuS3Jjkl621u6pqQZK9q+rdrbWre+O2TrJ3ku+01q7tc20AA3fhhZvkwgs36fu8k3107aMe1Z86piuP/gUAAAAAYKrrFAS31n7b5+sfm2TfJB/uPS/4+0num+R1SbZKclBrbfnW029Ocm6S86vquF7bIRl5zvFb+1wXAAAAAAAAwLTVdUVwX7XWfltVT0xyeJJnJXlpktuSXJLkra2100eNvaCqdklyZO/VklyQZO/W2k/WbeUAAAAAAAAAU1fnILiqZiV5YZInJdk8IytyR2uttdeu6XyttV8ledUajv1BRgJjAAAAAAAAAFaiUxBcVffNyPbMj0lSGVmVW73uNqptjYNgAAAAAAAAAPpr7Gre1TkyySOT7J9k+4wEv3+dZIckX0jyoyT362eBAAAAAAAAAHTTNQh+XpLPttY+k+TmXttdrbWft9b2ycjzfT/UzwIBAAAAAAAA6KZrELxlRlb9JsmdveOcUf1fTrLnJGsCAAAAAAAAYBK6BsE3JLl37/0tSe5I8sBR/Xck2bwPdQEAAAAAAAAwQV2D4F8keVSStNbuTvLfSV5dVbOraqMk+yb5dX9LBAAAAAAAAKCLrkHwN5L8bVXN7n3+aJInZWSl8PVJ5ic5pn/lAQAAAAAAANDVrI7jP5jkqNba7UnSWju1qu5Msk+Su5J8qbX2xT7XCAAAAAAAAEAHnYLg1lpLcvuYttOTnN7PogAAAAAAAACYuK5bQ/9Z77nA86pqg34WBAAAAAAAAMDkdA6Cq+qvquo7SW5JsjDJ03rt96+qb1fVbn2uEQAAAAAAAIAOOgXBVfX4JOcn2T7JZ0f3tdauT7Jhklf1qzgAAAAAAAAAuuu6IviIJFcneXSSf0hSY/q/neSJfagLAAAAAAAAgAnqGgQ/PcmJrbUlSdo4/QuTbD3pqgAAAAAAAACYsK5B8Jwkf1xF/yaTqAUAAAAAAACAPugaBP8qyRNW0f/MJD+beDkAAAAAAAAATFbXIPiUJK+sqt1GtbUkqaq3Jnl2ks/1qTYAAAAAAAAAJmBWx/FHJdk9yTlJLs9ICHxMVc1NsmWSbyY5vq8VAgAAAAAAANBJpxXBrbVlGQmC35bktiRLkzw8yeIkhyX5m9ba3f0uEgAAAAAAAIA113VFcFprdyY5pvcCAAAAAAAAYIrp+oxgAAAAAAAAAKa4ziuCk6Sqdk/ysCT3S1Jjultr7f2TLQwAAAAAAACAiekUBFfVI5OckZHnAo8NgJdrSQTBAAAAAAAAAAPSdUXwvyZ5YJK3JDk/yY39LggAAAAAAACAyekaBD8xyYdba8etjWIAAAAAAAAAmLwZHcf/IcnitVEIAAAAAAAAAP3RNQj+jyQvXAt1AAAAAAAAANAnXbeGfleSL1XVGUk+nuTKJHeNHdRaWzj50gAAAAAAAACYiK5B8B1Jfprk7Un2XMW4mROuCAAAAAAAAIBJ6RoEfyTJoUn+O8l/Jbmx7xUBAAAAAAAAMCldg+BXJjmjtfa3a6MYAAAAAAAAACZvRsfxGyX5xtooBAAAAAAAAID+6BoEX5jk0WujEAAAAAAAAAD6o2sQ/NYkf1dVL14bxQAAAAAAAAAweV2D4GOT3JLktKpaWFXfrarvjHl9u2sRVXXfqjqqqn5ZVUuralFVnVtVTx8z7klV9a2quqWqbq6qs6vq8V2vBwAAAAAAADDMZnUc/5AkLcnC3ucHTbaAqto2yXlJNk7y6SS/SLJpksclmTdq3JN7465Kcniv+eAk51fVU1prl062FgAAAAAAAIBh0CkIbq1ttxZq+PdeHY9rrV2zinEfT7Isyc6ttauSpKpOTXJZkqOT7LEWagMAAAAAAACYdrpuDd1JVW1SVSdV1SNX0r9zkqcl+Uhr7ZqquldVbTTOuIcm2THJactD4CTpvT8tyW5VteXa+RYAAAAAAAAA08taDYKTbJjkVUm2Xkn/c3vHhVX11SS3JflTVf2iqvYZNW7H3vEH48xxYZJK8oQ+1AsAAAAAAAAw7a3tIDgZCWlX5hG944lJ7puR0Hi/jGwB/bmqek2vf3mQfFXuaXnbvHH6UlUHVNWCqlqwaNGiToUDAAAAAAAATEfrIghelfv0jrck2bW19vnW2meSPD3JTUk+WFUzkizfLvr2ceZY2jveY0vpJGmtndBam99amz937tz+VQ4AAAAAAAAwRQ06CL6td/xCa23Z8sbW2o1JzkyyZUZWDd/a65o9zhxzesdbx+kDAAAAAAAAWO8MOgj+fe947Th91/SOmye5uvd+vO2fl7eNt200AAAAAAAAwHpn0EHwRb3jNuP0LW+7PsmPeu93Gmfck5O0JBf3tzQAAAAAAACA6WnQQfCXM/J84H2qauPljVW1VZIXJvlFa+2XrbVfJlmQZO+q2nrUuK2T7J3kO6218VYVAwAAAAAAAKx3Zg3y4q21G6vqbUn+NcmFVXVSkg2SvKF3PGTU8DcnOTfJ+VV1XK/tkIyE2W9dd1UDAAAAAAAATG1rOwheluS7SW5c2YDW2glVtTjJYUnen+TuJD9I8vLW2vdHjbugqnZJcmTv1ZJckGTv1tpP1tYXAAAAAAAAAJhu1moQ3Fq7McmuazDu9CSnr8G4HyR5Vh9KAwAAAAAAABhanYPgqtopycFJHpbkfklqzJDWWtu+D7UBAAAAAAAAMAGdguCq2jfJZ5LckeQXSRaujaIAAAAAAAAAmLiuK4LfleTnSXZrrV29FuoBAAAAAAAAYJJmdBy/bZJ/EQIDAAAAAAAATF1dg+DfJ5m9NgoBAAAAAAAAoD+6BsGfTPKKqpq5NooBAAAAAAAAYPK6PiP44iR7Jbmoqv45yW+S3DV2UGvte32oDQAAAAAAAIAJ6BoEf3vU+08laWP6q9dmxTAAAAAAAADAgHQNgl+zVqoAAAAAAAAAoG86BcGttZPXViEAAAAAAAAA9MeMQRcAAAAAAAAAQH91DoKr6oFVdVJV/b6qllXVM3vtc3vtO/a/TAAAAAAAAADWVKcguKoenGRBkr2S/DTJzOV9rbVFSeYn2b+fBQIAAAAAAADQTadnBCf5QJK7kzwmyW1Jrh/T/7Ukz+9DXQAAAAAAAABMUNetoXdLcnxr7XdJ2jj9v02yzaSrAgAAAAAAAGDCugbBmyS5ZhX9G6T7KmMAAAAAAAAA+qhrEPy7JI9eRf+Tk/xy4uUAAAAAAAAAMFldg+DTk+xXVY8Z1daSpKr2SrJ3klP7VBsAAAAAAAAAE9A1CP5Akt8n+WGSf89ICPwPVfWDjATAP0lydF8rBAAAAAAAAKCTTkFwa+3mJDsl+VSS+Ukqye5JHpHk+CS7ttaW9rtIAAAAAAAAANbcrK4n9MLgNyd5c1XNzUgYvKi11vpdHAAAAAAAAADddQ6CR2utLepXIQAAAAAAAAD0xyqD4Kp60EQmba0tnFg5AAAAAAAAAEzW6lYEX5lkIls+z5zAOQAAAAAAAAD0weqC4CMysSAYAAAAAAAAgAFZZRDcWnvvOqoDAAAAAAAAgD6ZsTYnr6otqurXVbXT2rwOAAAAAAAAAP9rrQbBGXlW8HZJNlzL1wEAAAAAAACgZ20HwQAAAAAAAACsY4JgAAAAAAAAgCEjCAYAAAAAAAAYMoJgAAAAAAAAgCEjCAYAAAAAAAAYMlMqCK6qjarq11XVquoT4/Q/oqq+XFU3VtWfqur8qnrmIGoFAAAAAAAAmKqmVBCc5Igkc8frqKrtk1yQZKckH0ny9iQbJzmnqnZbZxUCAAAAAAAATHFrOwhekuR9SX69uoFV9VdJ3pLkPSsZ8qEkmyX569bah1prxyd5epKrk/xzVVU/CgYAAAAAAACY7iYUBFfVzlV1ZFWdWFWP7LVt3GvfbPm41tqfWmvva61duZr5ZiY5McnZSU4fp//eSfZMcl5r7ZJR8y9J8qkkD0+y40S+CwAAAAAAAMCw6RQEV9XMqvpiknOT/GOS/ZJs3eu+M8mXk7xxAnUcmuSRSQ5eSf/jksxO8oNx+i7sHQXBAAAAAAAAAOm+IvgdSfZK8vdJdkjy5+2YW2tLk5yR5LldJqyqB2dk++gjVrFyeHnYfNU4fcvb5q1k/gOqakFVLVi0aFGX0gAAAAAAAACmpa5B8L5JPtta+1iSxeP0X5Zk+45zfjIjzxD+6CrGbNQ73j5O39IxY1bQWjuhtTa/tTZ/7ty5HUsDAAAAAAAAmH66BsHbZfztmZe7KcnmazpZVe2TZPckb2it3bGKobf2jrPH6ZszZgwAAAAAAADAem1Wx/G3JLnvKvofmmSN9l+uqtkZWQX8tSTXVtVDe13Lt3jetNe2OMnVY/pGW9423rbRAAAAAAAAAOudriuC/yvJPlVVYzuqavMk+yU5dw3n2jDJ3CTPS3LFqNd5vf59ep/3T3JpRraF3mmceZ7cOy5Yw+sCAAAAAAAADLWuK4I/kJEw+DtJ/q3X9hdV9bAk/5Dk3kk+vIZz/SnJ3uO0z01yfJKzk3w6yf9rrS2pqq8meXFV/UVr7SdJUlUbZyQoviLJRR2/CwAAAAAAAMBQ6hQEt9YWVNVeST6V5DO95qOSVJLrk7yotfazNZzrjiRfGtteVdv13v6qtTa6/51JnpXkG1V1TJKbk7wuI1tDP6+11rp8FwAAAAAAAIBh1XVFcFprZ/XC2t2T7JCREPiKJOe01m7tb3krXPeXVfXUjKw4/ockGyT5cZJnt9a+tbauCwAAAAAAADDddA6Ck6S1dnuS/9t79VVr7cqMhMvj9V2W5AX9viYAAAAAAADAMJkx6AIAAAAAAAAA6K9Vrgiuql9PYM7WWtt+gvUAAAAAAAAAMEmr2xp6YZI2pm2bJNsnuTnJ8qD4IUk2SfKrJL/vZ4EAAAAAAAAAdLPKILi1tsvoz1X1V0m+leQtST7ZWlvWa98gyRuTvDvJ362NQgEAAAAAAABYM12fEXxUklNbax9fHgInSWttWWvt2CRfSvL/9bE+AAAAAAAAADrqGgQ/Mcklq+j/794YAAAAAAAAAAakaxB8W5InraJ/pyRLJ14OAAAAAAAAAJPVNQj+cpJ9q+rwqtp4eWNVbVxV70myT28MAAAAAAAAAAMyq+P4tyf5iyTvTfJPVXVNr32r3lw/7o0BAAAAAAAAYEA6rQhurd2U5ClJXp/km0lu7b2+2WvbqTcGAAAAAAAAgAHpuiI4rbU7k5zQewEAAAAAAAAwxXR9RvAKqmqLqtqiX8UAAAAAAAAAMHmdg+Cq2rqqTq6qm5Jcl+S6qrqxqv6tqub1vUIAAAAAAAAAOum0NXRVPSjJhUm2THJJkp/2uh6VZN8ku1fVk1trv+tnkQAAAAAAAACsua7PCH5/ks2T/E1r7WujO6rqOUlO7415dV+qAwAAAAAAAKCzrltD75Hk+LEhcJK01r6e5F+SPLsfhQEAAAAAAAAwMV2D4M2TXLGK/iuSbDbhagAAAAAAAACYtK5B8O+T7LKK/p17YwAAAAAAAAAYkK5B8GlJ9q6qD1XVpssbq2qTqvpgkpck+WI/CwQAAAAAAACgm1kdx78/ydOTvCPJ26rq6l771klmJvl+kiP7Vx4AAAAAAAAAXXVaEdxauzUjW0MfmOQbSf7Ue52T5IAku7bWbutzjQAAAAAAAAB00HVFcFprdyY5sfcCAAAAAAAAYIrp+ozgcVXVFlX1sH7MBQAAAAAAAMDkdAqCq2rfqjphTNuHk1yX5PKq+n5V3aefBQIAAAAAAADQTdcVwQdm1HbSVTU/yWFJzs/IVtFPTPL3fasOAAAAAAAAgM66PiP4oUlOG/V57yQ3JNmjtbasqlqSlyR5X5/qAwAAAAAAAKCjriuCN03yx1Gfn5XkW621Zb3PC5I8qB+FAQAAAAAAADAxXYPga5M8LEmqam6Sx2dkW+jlNk5yV18qAwAAAAAAAGBCum4N/Z0kB1XVDUl2TdKSnDWq/xFJrupTbQAAAAAAAABMQNcg+PAkT0nykd7nI1trVyZJVc1KsleS/+xbdQAAAAAAAAB01ikIbq39vqoeneRRSf7YWls4qnujJAck+Ukf6wMAAAAAAACgo64rgtNauyvJpeO035zkK/0oCgAAAAAAAICJmzHoAgAAAAAAAADor1UGwVV1d1XdWVUbjPp812ped67pxavq4VV1RFVdWFWLquqWqrqkqt5VVfceZ/wjqurLVXVjVf2pqs6vqmd2/9oAAAAAAAAAw2t1W0N/NklLcteYz/2yX5KDkpyZ5PNJ7kiya5Ijk7ykqp7cWrstSapq+yQXJLkzyUeS/DHJ65KcU1XPaa19q491AQAAAAAAAExb1Vo/c92OF6+an+SK1tofx7QfmeRdSQ5prX2i13Zqkr2SPKG1dkmvbeMkP02yNMkj22q+zPz589uCBQv6VHtfppnWJvujs77fQ/dvcty/yXH/Jqff/+msqotba/P7OysAAAAAAOuzgT4juLW2YGwI3PPF3vExSdLbJnrPJOctD4F75y9J8qkkD0+y49qtFgAAAAAAAGB6WN3W0OOqqq2TPD/JQ3pNv07yf1trV/Wprm16x+t6x8clmZ3kB+OMvbB33DHJRX26PgAAAAAAAMC01TkIrqp3J/mn3rmjNwc9rqo+0Fp732QKqqqZSd6dkWcBn9Jr3rp3HC9oXt42bzLXBQAAAAAAABgWnbaGrqqDk7wvySVJXpHk8b3XK3pth/fGTMaxSXZKcnhr7ee9to16x9vHGb90zJixNR9QVQuqasGiRYsmWRoAAAAAAADA1Nf1GcGHZGT75ae21v6jtfb/eq8vJHlqkot7Yyakqt6f5OAkJ7TWPjSq69becfY4p80ZM2YFrbUTWmvzW2vz586dO9HSAAAAAAAAAKaNrkHwg5J8obV259iO1todST7fG9NZVb03I1tOfybJ68d0X907jrf98/K2fj2fGAAAAAAAAGBa6xoEL0xyn1X036c3ppNeCPyeJCcn2b+11sYMuTQj20LvNM7pT+4dF3S9LgAAAAAAAMAw6hoEfyLJgVW11diOqpqXkZW8x3WZsKoOz0gI/Lkk+7XW7h47prW2JMlXk+xSVX8x6tyNk+yf5IqMbFkNAAAAAAAAsN6b1XH8H5Ncl+Tyqvr3JJf32ndI8ookv0hyc1XtO/qk1tpnx5usqg5K8r6MrCL+VpKXV9XoIde11r7Ze//OJM9K8o2qOibJzUlel5GtoZ83zipiAAAAAAAAgPVSdclPq+oeq3XXQGutzVzJfP+W5FWrOPe7rbVdRo3fIcmHkzwjyQZJfpzkva21b61JIfPnz28LFvRnB+kV8+r102Sj9/X9Hrp/k+P+TY77Nzn9/tWjqrq4tTa/v7MCAAAAALA+67oieNd+Xry19uokr+4w/rIkL+hnDQAAAAAAAADDplMQ3Fr77toqBAAAAAAAAID+mDHRE6tqdlXNq6oN+lkQAAAAAAAAAJPTOQiuqr+qqu8kuSXJwiRP67Xfv6q+XVW79blGAAAAAAAAADroFARX1eOTnJ9k+ySfHd3XWrs+yYZJXtWv4gAAAAAAAADoruuK4COSXJ3k0Un+IUmN6f92kif2oS4AAAAAAAAAJqhrEPz0JCe21pYkaeP0L0yy9aSrAgAAAAAAAGDCugbBc5L8cRX9m0yiFgAAAAAAAAD6oGsQ/KskT1hF/zOT/Gzi5QAAAAAAAAAwWV2D4FOSvLKqdhvV1pKkqt6a5NlJPten2gAAAAAAAACYgFkdxx+VZPck5yS5PCMh8DFVNTfJlkm+meT4vlYIAAAAAAAAQCedVgS31pZlJAh+W5LbkixN8vAki5McluRvWmt397tIAAAAAAAAANZc1xXBaa3dmeSY3gsAAAAAAACAKabrM4IBAAAAAAAAmOIEwQAAAAAAAABDRhAMAAAAAAAAMGQEwQAAAAAAAABDRhAMAAAAAAAAMGQEwQAAAAAAAABDRhAMAAAAAAAAMGQEwQAAAAAAAABDRhAMAAAAAAAAMGQEwQAAAAAAAABDRhAMAAAAAAAAMGQEwQAAAAAAAABDRhAMAAAAAAAAMGQEwQAAAAAAAABDRhAMAAAAAAAAMGQEwQAAAAAAAABDRhAMAAAAAAAAMGQEwQAAAAAAAABDRhAMAAAAAAAAMGQEwQAAAAAAAABDRhAMAAAAAAAAMGSmVRBcVTOq6tCquryqllbV76rq6Kq696BrAwAAAAAAAJgqplUQnOSYJB9N8rMkhyQ5Lcmbkny1qqbbdwEAAAAAAABYK2YNuoA1VVWPzkj4e3prba9R7b9J8vEkL01yyoDKAwAAAAAAAJgyptMq2pclqSTHjmk/McmtSfZZ1wUBAAAAAAAATEXTKQjeMcndSS4a3dhaW5rkkl4/AAAAAAAAwHpvOgXBWydZ3Fq7fZy+q5JsUVUbrOOaAAAAAAAAAKacafOM4CQbJRkvBE6SpaPGLBvdUVUHJDmg93FJVf187ZQ3EFskWTyoi1cN6sp94/5Njvs3Oe7f5Azb/du27zMCAAAAALBem05B8K1J7r+SvjmjxqygtXZCkhPWVlGDVFULWmvzB13HdOX+TY77Nznu3+S4fwAAAAAAsGrTaWvoqzOy/fPscfrmZWTb6GXj9AEAAAAAAACsV6ZTEPyjjNT7xNGNVTUnyeOTLBhATQAAAAAAAABTznQKgr+YpCV5y5j212Xk2cCfX9cFTQFDueX1OuT+TY77Nznu3+S4fwAAAAAAsArVWht0DWusqo5LcnCSM5J8LckOSd6U5PtJntlau3uA5QEAAAAAAABMCdMtCJ6ZkRXBByTZLsnijKwUPry1tmRwlQEAAAAAAABMHdMqCAYAAAAAAABg9abTM4LXe1U1o6oOrarLq2ppVf2uqo6uqnsPurbpoKreWVWnVdWvq6pV1ZWDrmk6qaqHV9URVXVhVS2qqluq6pKqepefwe6qaqNRP4ufGHQ900FVbVxV/1hVl/Z+/hZX1QVV9eqqqkHXBwAAAAAAU8msQRdAJ8dk5JnIZyQ5Ov/7jOS/rKrdPCN5tT6Y5IYkP06y2WBLmZb2S3JQkjOTfD7JHUl2TXJkkpdU1ZNba7cNsL7p5ogkcwddxHRRVTOSfD3JU5KcnOS4JBsleVmSz2Tk38N3DKxAAAAAAACYYmwNPU1U1aOTXJrkjNbaXqPaD0ny8SSvaK2dMqj6poOqekhr7de99/+TZOPW2naDrWr6qKr5Sa5orf1xTPuRSd6V5JDWmpWta6Cq/irJRUkOy8gvdfxza+3gwVY1tVXVTkkuSHJsa+3QUe0bJLk8yX1ba5sNqDwAAAAAAJhybA09fbwsSSU5dkz7iUluTbLPui5oulkeAjMxrbUFY0Pgni/2jo9Zl/VMV1U1MyN/b89OcvqAy5lONukdrx7d2FpblmRxkj+t84oAAAAAAGAKszX09LFjkrszsorwz1prS6vqkl4/DMI2veN1A61i+jg0ySOT7LW6gazgoiQ3JTms93zvH2Zka+hXJXlCktcPrDIAAAAAAJiCBMHTx9ZJFrfWbh+n76okT6mqDXqr42Cd6K1ufXeSO5PYmnw1qurBSd6X5IjW2pVVtd2AS5o2Wms3VtWeST6V5NRRXbck2au19uWBFAYAAAAAAFOUraGnj42SjBcCJ8nSUWNgXTo2yU5JDm+t/XzAtUwHn0zy6yQfHXQh09SSJP+T5KgkL06yf5JfJjmlqnYfZGEAAAAAADDVWBE8fdya5P4r6ZszagysE1X1/iQHJzmhtfahQdcz1VXVPkl2T7Jza+2OQdcz3VTVY5NckOTQ1tonR7V/ISPh8IlVtX1r7a5B1QgAAAAAAFOJFcHTx9VJtqiq2eP0zcvIttG2hWadqKr3JvmnJJ+JZ7OuVu/v7UeTfC3JtVX10Kp6aJJte0M27bVtNqgap4FDM/JLL6eNbmyt3ZrkrIzcy+3WfVkAAAAAADA1CYKnjx9l5M/riaMbq2pOkscnWTCAmlgP9ULg9yQ5Ocn+rbU22IqmhQ2TzE3yvCRXjHqd1+vfp/d5/0EUN03M6x1njtM3a8wRAAAAAADWe4Lg6eOLSVqSt4xpf11Gng38+XVdEOufqjo8IyHw55Ls11q7e8AlTRd/SrL3OK839vrP7n0+cyDVTQ8/6x1fPbqxt4r6BUluzMjzggEAAAAAgCRlMd/0UVXHZeSZrGdkZIvZHZK8Kcn3kzxTKLdqVfXK/O9WvIck2SDJ0b3Pv22tfW4ghU0TVXVQkk8kWZjk3UnG/rxd11r75jovbBqrqu2S/CbJP7fWDh5wOVNaVW2b5MdJNs/IL758P8l9M/LLMNslOai1dvzACgQAAAAAgClGEDyNVNXMjKwIPiAjwcfijKwUPry1tmRwlU0PVXVekmespPu7rbVd1l01009V/VuSV61iiHvYkSC4m6raPsnhSZ6V5AFJbktySZJjW2unD7A0AAAAAACYcgTBAAAAAAAAAEPGM4IBAAAAAAAAhowgGAAAAAAAAGDICIIBAAAAAAAAhowgGAAAAAAAAGDICIIBAAAAAAAAhowgGAAAAAAAAGDICIIBAAAAAAAAhowgGAAAAAAAAGDICIIBAAAAAAAAhowgGAAAAAAAAGDI/P+QB1wv/xvOTwAAAABJRU5ErkJggg==\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ - "# This and the next cell do the same as the previous 2 cells but plot episode mean lengths instead of episode reward\n", + "# This and the next cell do the same as cells 3 and 4 but plot episode mean lengths instead of episode reward\n", "mdpp_analysis.plot_1d_dimensions(list_exp_data, save_fig, metric_num=-1, plot_type = \"agent\")" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": { - "scrolled": false + "scrolled": true }, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ - "mdpp_analysis.plot_1d_dimensions(list_exp_data, save_fig, train=False, metric_num=-1, plot_type = \"agent\")" + "if load_eval:\n", + " mdpp_analysis.plot_1d_dimensions(list_exp_data, save_fig, train=False, metric_num=-1, plot_type = \"agent\")" ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/mnt/484A4CAB4A4C9798/GoogleDrive/Maestria-Drive/HiWi/mdp-playground/mdp_playground/analysis/analysis.py:546: UserWarning: FixedFormatter should only be used together with FixedLocator\n", - " plt.gca().set_xticklabels(tick_labels[0])\n" - ] - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABasAAAFCCAYAAAD/g4GlAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAvnElEQVR4nO3de7xtZVk3/N+1VUAgIQVTICXxrHkIMbEnj/W+lq9ZmqWGyoNIB/FA9VSmIqJJqSiJlm01T0kPaIT66FOJBlmIgEriAUQRDyDk9oAi4AGu9485dy4Xc6+95t5rrjH3Wt8vn/EZa97jHve4FvuzxP3b975GdXcAAAAAAGBIG4YuAAAAAAAAhNUAAAAAAAxOWA0AAAAAwOCE1QAAAAAADE5YDQAAAADA4ITVAAAAAAAM7qZDFwAAAAAAsN7dsu7Y3881U91zdb7yz939iBmVtOqE1QAAAAAAA/t+rsn96mlT3XNGH7vXjMoZhDYgAAAAAAAMzs5qAAAAAIB5UFPO75lUMRhhNQAAAADAwCpJbZgyrb5hJqUMRlgNAAAAADC0SmrandVrjLAaAAAAAGAerPO0WlgNAAAAADAH1nlWLawGAAAAABheTd+zeo0RVgMAAAAADK2y7rdWC6sBAAAAAObAOs+q109YfbPatXfJnkOXAczQev8fdABYCzbcdMPQJQAzttft9hi6BGDGPve5T23q7r2HrmNHM9pYvb7DjXUTVu+SPXNgDh+6DGCGbrrzTYYuAQDYTrvtdfOhSwBm7NCX/tLQJQAz9pjH3usLQ9eww1rfWfX6CasBAAAAAOZWxQsWhy4AAAAAAAAtToXVAAAAAADzYJ2n1cJqAAAAAIA5sM6zamE1AAAAAMDgqvSsHroAAAAAAACy7rdWbxi6AAAAAAAAEFYDAAAAAAysMtpYPc2xrHWr7lJVb6uqT1fVVVV1TVVdWFWvqKrbbmH+aVX1jar6TlV9sKoetsLf7kTagAAAAAAAzIGaTRuQ/ZLcNsk/Jvlykh8k+ekkRyR5fFXdp7v/a/z8A5KcNZ7z0iRXJXlakn+uql/q7tNnUeBmwmoAAAAAgHkwg6y6u9+f5P03elTVvyU5JcmhGQXTSXJckj2THNjd54/nvSXJJ5O8pqru2t298lWOaAMCAAAAADC0SmpDTXVspy+Mzz+eJFW1W5JfSXLG5qA6Sbr76iSvT3LnJAdt70OXYmc1AAAAAMA8mEkXkPHSVbsk2T3JLknunuQvxpfeOz7fK8nOST404fazx+eDkpwzqxqF1QAAAAAAc2AbelbvVVXnLfi8sbs3bmHu4UlOXPD50iSHdPcHx5/3GZ8vm3Dv5rF9py1wGsJqAAAAAIDB1baE1Zu6+37LnHtakgsz2l1934xafuy14Pqu4/N3J9x73aI5MyGsBgAAAAAYWmWmbxjs7i8n+fL442lV9Q9Jzq2qXbv7uCTXjK/tPOH2XcbnayZcWzFesAgAAAAAMLDKqA3INMf26O6PJ/lYkt8bD10+Pk9q9bF5bFKLkBVjZzUAAAAAwBzYzvx5W9w8yS3HX1+QUQuQgyfMe8D4fN6EaytmVXZWV9WTq+pjVXVtVV1ZVa+vqr23ca0NVfWhquqq+j8rXSsAAAAAwCCqpjuWtWTdZgvjD01yzyRnJ0l3X53k3UkeUlX3XjBv94xeznhxknO27xtc2sx3VlfVUUlekeTMJM9Ksl+S309ycFXdv7u/M+WSv5fRv0QAAAAAgLVh+fnztP66qm6b5ANJvpBR/+kDkzw+ybeT/MGCuc9J8vAk/1JVr0zyrSRPy6gNyCO7u2dS4dhMw+qq2ivJi5Ocm+Th3X39ePzcJO/KKLx+yRTr7Tee/4Ikx694wQAAAAAAA6kNM0mr/z7Jk5M8KcneSTqj0Ppvkrysu7+4eWJ3f7aqfi7Jnyf5kyQ7Jflokkd09+mzKG6hWe+s/tUkuyY5cXNQnSTd/e6quiTJIZkirE7ymiSXJPnLCKsBAAAAgLVkBluru/uUJKdMMf/TSR694oUsw6zD6oPG5w9NuHZ2kidU1e7jfihLqqpfT/KoJA/s7uu3922XAAAAAADzojLICxbnyqxfsLjP+HzZhGuXZfRrsM+Eaz+iqvZI8qokf9PdZ69ceQAAAAAAc6AqNeWx1ixrZ3VV7Znk2VOs+6ru/npGLUCS5LsT5lw3Pu864dpiL80oWH/OFDWkqo5IckSS7Jw9prkVAAAAAIBVtNw2IHtm9FLD5fq7JF9Pcs34885Jrl00Z5fx+Zosoap+PqM3Tj6pu785RQ3p7o1JNibJj9U+M31TJQAAAADAdpl1H4w5t6ywursvzahlx7QuH5/3TfLZRdf2zejNk5dnaa9O8p9JPlxVd1x0bdfx2De7e9M21AcAAAAAMBfWYmuPacw6qz93fD54wrUHJLloGS9XvH2S+yS5eNGRJA8df33M9hYKAAAAADAkPatn650ZvRjxyKo6qbuvT5KqelSSOyR5/sLJVXW7jHpYf667vz8efnKSnSas/fYkH0ny57nxrm0AAAAAgB1HJaUNyOx091er6vlJXp7k9Kr6+4zaf/xBkguTnLDolrckeXCSn0py6XiNd01ae/wnB1d09ztmUTsAAAAAwKpag7ulpzHrndXp7uOr6mtJjspol/W3kpyS5E+W0QIEAAAAAGDNq6z7rHr2YXWSdPebkrxpGfMeMsWa6/yXDgAAAABYMyqpDes78lyVsBoAAAAAgKXUut9aLawGAAAAAJgD6zyrFlYDAAAAAMwDbUAAAAAAABiWNywKqwEAAAAA5sE6z6qF1QAAAAAAQ6toAyKsBgAAAACYB+s7qxZWAwAAAAAMrpJa531AhNUAAAAAAIMrbUCGLgAAAAAAAC9Y3DB0AQAAAAAAYGc1AAAAAMA8WOdbq4XVAAAAAABDq+hZPXQBAAAAAADrXWXdb6wWVgMAAAAAzIV1nlYLqwEAAAAA5kAJqwEAAAAAGFQltWHoIoa1zr99AAAAAIB5UKM2INMcy1m16s5VdWxVnV1VX62qb1fV+VX13KrabdHcY6qqt3D84Uy+7QXsrAYAAAAAmAMz6gJyWJKnJ3lXkrcl+X6ShyZ5cZLfqKoHdPe1i+45KsmmRWMfmUl1CwirAQAAAACGVkltmEla/Y4kx3X3VQvGXltVFyd5bpKnJnn1ontO6+5LZ1HMUrQBAQAAAACYBzNoA9Ld5y0Kqjc7eXy+5+RS6hZVtaqbnYXVAAAAAAADq8wkq17KfuPzlROufTzJVUmuq6qzquqXtvtpy6ANCAAAAADAHNiGNiB7VdV5Cz5v7O6NW31O1U2SPD/JD5KctODSN5NsTHJWkm8kuUuSZyd5T1Ud1t1vmrbAaQirAQAAAACGtm3bpTd19/224WknJDk4yZ9290WbB7v7hBuXVX+b5BNJXllV7+juq7fhecuiDQgAAAAAwBxYjTYgVfWiJEdmtAv7uK3N7+6vJXltkj2TPHDbnro8dlYDAAAAAMyBbWgDMt36VcckeV6SNyb5nSluvXR83muFS/oRwmoAAAAAgKFVUivw1sQtLj8Kql+Q5M1JDu/unuL2O43Pk17GuGK0AQEAAAAAWMOq6uiMguq3Jjmsu2+YMOemVbXHhPGfTPK7Sb6W0YsXZ8bOagAAAACAeTCDjdVV9fQkL0zyxSSnJ3nioh3cV3b3+5LsnuTzVXVakk8n+UaSuyQ5fHztCd197cpX+EPCagAAAACAgVVm1rP6oPH5dhm1AFnszCTvS3Jtkn9I8rNJfjWjgHpTRgH3S7v7nFkUt5CwGgAAAABgDsyiZ3V3H5rk0GXM+25Gu6gHI6wGAAAAABhaVTKbndU7DGE1AAAAAMAcmMHG6h2KsBoAAAAAYA7Mog3IjkRYDQAAAAAwtIo2IEMXAAAAAACANiAbVuMhVfXkqvpYVV1bVVdW1eurau9l3rtvVT2nqs6sqq9U1Xeq6pNV9bKqutWsawcAAAAAmLVKUhtqqmOtmXlYXVVHJXlzkquSPCvJ3yR5fJIzqmq3ZSzxqCTHJPlakpcleXaSs8bn86vqNiteNAAAAADAaqua7lhjZtoGpKr2SvLiJOcmeXh3Xz8ePzfJuzIKr1+ylWU+mOT23X3FgrHXVdWHk7wuyR+ODwAAAACAHVPVun/B4qx3Vv9qkl2TnLg5qE6S7n53kkuSHLK1Bbr7k4uC6s1OHp/vuQJ1AgAAAAAMqjZMd6w1s/6WDhqfPzTh2tlJ7lpVu2/j2vuNz1du4/0AAAAAAHOjxrurl3usNbMOq/cZny+bcO2yjPqG7zPh2nK8cHx+8zbeDwAAAAAwP/Ss3rqq2jOjFxou16u6++sZtQBJku9OmHPd+LzrhGtbq+cPkjwuycbu/sAS845IckSS7Jw9pn0MAAAAAMDqqLXZ2mMay33B4p5JXjDFun+X5OtJrhl/3jnJtYvm7DI+X5MpVNXhSV6W5D1JjlxqbndvTLIxSX6s9ulpngMAAAAAsFoqWZOtPaaxrLC6uy/N6N/XtC4fn/dN8tlF1/ZN0gvmbFVVHZZR+PwvSR7b3d/fhpoAAAAAAJgzs95Yfu74fPCEaw9IclF3X72chcZB9euTnJ7kV7t7UmsRAAAAAIAd04aa7lhjZh1WvzOj9h9HVtVNNg9W1aOS3CHJ2xZOrqrbVdVdq+pmi8YPTfK6JB9I8ujuvi4AAAAAAGtFVWrKY61Zbs/qbdLdX62q5yd5eZLTq+rvM2r/8QdJLkxywqJb3pLkwUl+KsmlSVJVv5LkDUm+leTkJI9d9AtxdXefNrNvAgAAAABgFazB/HkqMw2rk6S7j6+qryU5KsmrMgqdT0nyJ8tsAfIzGe0A3zPjlyUu8oUkp61IsQAAAAAAQ1mDrT2mMfOwOkm6+01J3rSMeQ+ZMHZMkmNWuCQAAAAAgLmyFlt7TGNVwmoAAAAAAJZQ2oAIqwEAAAAA5oE2IAAAAAAADKmiDYiwGgAAAABgaFUpO6sBAAAAABjc+s6qhdUAAAAAAPNAGxAAAAAAAAanDQgAAAAAAMMqO6s3DF0AAAAAAAAZ9aye5ljOklV3rqpjq+rsqvpqVX27qs6vqudW1W4T5t+lqk6rqm9U1Xeq6oNV9bAV+f62ws5qAAAAAICBVWa2s/qwJE9P8q4kb0vy/SQPTfLiJL9RVQ/o7mszev4BSc5K8oMkL01yVZKnJfnnqvql7j59Yu1VD562qO4+c/GYsBoAAAAAYA7MqAvIO5Ic191XLRh7bVVdnOS5SZ6a5NXj8eOS7JnkwO4+f1RTvSXJJ5O8pqru2t094RkfyLL3ev+3G3X9EFYDAAAAAKxR3X3eFi6dnFFYfc8kGbcE+ZUkZ2wOqsf3X11Vr09ybJKDkpwzYa0/zI3D6jslOSLJC5Jcs2D8Z5I8cVJBwmoAAAAAgDmwyu9X3G98vnJ8vleSnZN8aMLcs8fniWF1d79y8di4z/VvJ/nr7v7agvEnRlgNAAAAADCnqmbVs3rCo+omSZ6fUW/qk8bD+4zPl024ZfPYvlM85mabH7f48Vu6QVgNAAAAADAHtiGr3quqFrb52NjdG5dx3wlJDk7yp9190Xhs1/H5uxPmX7doznL89Ph8mySbFozfJsl3Jt0grAYAAAAAGFgl27KzelN332+q51S9KMmRGQXbxy24tLmv9M4Tbttl0ZytPePgJH88/vi7SZ4+Ht81yZOTfGbSfTd64yIAAAAAAKuvarpj+vXrmCTPS/LGJL+z6PLl4/OkVh+bxya1CFm4/gFV9aYk/57ks0n+IcnvVtVHq+qUJBdmtOP6rZPut7MaAAAAAGAOzLJn9TiofkGSNyc5vLt70ZQLMmoBcvCE2x8wPp834Vqq6q5Jnpvk8RltkD45ozB8l4yC7p9Ncu8knWRjkhMnrSOsBgAAAAAY2jbull7W0lVHZxRUvzXJYd19w+I53X11Vb07yWOq6t7d/Z/je3dPcniSi5Ocs4VHXJBRSP3+JEd399nj8W8leWBV3THJLZN8rru/tqU6hdUAAAAAAHOgsvJpdVU9PckLk3wxyelJnrhoB/eV3f2+8dfPSfLwJP9SVa/MKGx+Wka7ox85YTf2Zv+WUUj9H1V1y6q6f0a7qC/q7m9192eXU6uwGgAAAABgYKMXLM5k6YPG59tl1AJksTOTvC9JuvuzVfVzSf48yZ8k2SnJR5M8ortP39IDuvvhVbXfeGf2Lyf/nbrfUFXvSXJkd39pa4UKqwEAAAAA5sAswuruPjTJoVPM/3SSR0/zjKq6ZUYvVbxtklOSfC/JIUn+NsmvJDm7qg7s7iuWWmfDNA8FAAAAAGA2qmqqY478cUZB9YO6+wkZ7eCujNqK3DejTdMv2NoidlYDAAAAAMyB+cqfp/LoJG/p7g8vvtDdX6mqNyT5ra0tIqwGAAAAABha1Y6cVt8uyceWuP65JLfZ2iLCagAAAACAObDjZtW5Lku3nL5jkk1bW0RYDQAAAAAwsErmrQ/1NL6U5A4TxquqfibJ7yX531tbxAsWAQAAAADmwOZOIMs95sj7M+pbvVAn+WCSDye5IsnztraIndUAAAAAAGyPjUm+WVV7dfemJNcmuSTJ15L8fZJXdve3t7aIsBoAAAAAYA7sqG1AuvvCJMcu+PyhJHeadh1tQAAAAAAAhjZlC5AdKdeuqptV1YO2Ns/OagAAAACAObAD5c9LqqoNSe6X5GHj4+eS3Dxb2TwtrAYAAAAAGFhlx20DkiRVda/8MJx+UJJbZPSSxcuSvCPJB7a2hrAaAAAAAGAO7KhZdVX9V5K9xh83JfnnjMLpD3T3xctdR1gNAAAAADAHduCd1bfMaBf1hUleleT07v7ctIsIqwEAAAAA5sCOm1XnwflhC5ATkuxcVV9M8q/54Q7ry7a2yJINrVdKVW2oqqOq6sKquq6qvlRVx1fVbqtxPwAAAADAXKtKTXnMi+7+j+5+UXc/NMmPJ/nFJG9Lcrckb0jypaq6aGvrrEpYneSVSV6R5FNJnpHk7UmemeTd4zdDzvp+AAAAAIC5NXrB4nTHPOru67r7/UlenuQvkpyS5Pokd9ravTNvA1JV98goYD61ux+7YPzzGfUveXySk2Z1PwAAAADAjmBeA+jlGHfBeFBGrUAenuTeGWXwn0ryVxm1A1nSauxKfkJGRZ2waPx1Sa5JcsiM7wcAAAAAmHs7ahuQqvr3JN9I8p4kj03y0Yxy29t29z27+1nd/c6trbMaL1g8KMkNSc5ZONjd11XV+ePrs7wfAAAAAGDuzVH+PK2D88Nd1H+b0YsVz+/unmaR1dhZvU+STd393QnXLkuyV1XtNMP7AQAAAADmW+24O6uTPC3J3ye5ZZKXJflIkq9W1alV9YyquvtyFlmNndW7JpkUNCfJdQvmfG+l76+qI5IckSQ7Z4/l1AoAAAAAMIy5yp+Xr7v/NqMd1amqu2XUt/phSR6c5NGj4fqv7r7NUuusRlh9TZJbb+HaLgvmrPj93b0xycYk+bHaZ6ot5wAAAAAAq6WSedstvU26+9NJPp3kNUlSVfdN8tCMXrq4pNUIqy9Pcveq2nlCK499M2rxsaVd1StxPwAAAADA3FsLYfVi3f2xJB9L8oqtzV2NntXnjp9z/4WDVbVLkvskOW/G9wMAAAAAzL2q6Y55UlUbquoeVXWvbV1jNcLqk5N0kmcvGn9aRr2m37Z5oKoOqKq7buv9AAAAAACsrqr6yST/meSCJOdX1flVtff42s2r6iVVddDW1pl5G5DuvqCqXpPkyKo6Ncl7k9wtyTOTnJnkpAXT35/k9lnQSnzK+wEAAAAAdjxVO3IbkJcnOSDJsUluSPKcJH+W5IjuvraqHpLktkn+51KLrEbP6mS0K/rSJEckeWSSTUlOTHJ0d9+wCvcDAAAAAMyt0QsWh65imz0kyWu6+5hktJs6o2D6iPH105P85tYWWY02IOnu67v7+O6+S3fv3N37dvfvd/fVi+bt3903+iVZ7v0AAAAAADuqGu+uXu6xzDWfU1Vvr6pLqqqr6tIl5r5pPGfS8etLPGa3JBct+PyRJLceh9ZJ8oUk+22t1tXaWQ0AAAAAwBJm1AbkJUm+nuSjSfZc5j1PmjB2zhLzP5HkLgs+XzU+3zzJtUluleT6rT1UWA0AAAAAMLSaWRuQA7r7kiSpqk8k2X1rN3T33035jOOSvKWq3tzdn8gPg+kNVbVLkqck+fjWFhFWAwAAAADMgVnsrN4cVE9ZRyX5sSRXL/OdgffJqA3IeVV1WpIfjMePTfKwJHdO8pitLSKsBgAAAAAYWCWpDXPzhsWrMgqrv1dV/5bked394SXmH73g68eNz53kt5N8OskTu/u0rT1UWA0AAAAAMAdm1AZkGlckeWVGL0j8TpJ7J3l2kg9W1S939+lbuO+nJozdkOSb3X31ch8urAYAAAAAGFrVtrQB2auqzlvweWN3b9zWErr7TxYNnVZVJyU5P8lfJ7nTFu774rY+cyFhNQAAAADAHNiGndWbuvt+Myjlv3X3xVV1SpJDq+rO3f2ZWT1LWA0AAAAAMAdm8YLFFXLp+LxXkhuF1VX1xmWsUd196FIThNUAAAAAAAOrzHVYvbn9x5VbuP6kjL6FSSqjly1WkkOXesiGbakMAAAAAICVVTXdsbLPrt2qapcJ4/dN8rgkn+7uz026t7tv2t03WXgk2S3JfZK8NcnHk9x6azXYWQ0AAAAAMLTR1uqVX7bqSUluP/64d5Kdqup5489f6O63jr++U5L/W1WnJbk4yXeS3DvJYUmuT3LENM/t7uuSXJDkKVX13iQvHa+1RcJqAAAAAIA5MKM2IE9N8uBFYy8an8/MaOdzklyR5PQkD03yW0lunuQrSU5Oclx3X7gdNfyfJEdvbZKwGgAAAABgDswiq+7uhyxz3hUZ9Z6ehd2S7FVVu4x3XE+kZzUAAAAAACuiqjZU1U+Mj83x+xuS3CHJ95e6V1gNAAAAADC4Sm2Y7pgnVXWHqjopyTczah/ylSRXjcdu0d1f7O7rl1pDGxAAAAAAgIFVzaYNyGqoqnsk+fckt0hyXpLN/a3vmuQ3kzyiqn6+uz+51DrCagAAAACAOTCjFyyuhuOT3CzJw7r7zIUXqupBSd4znvOIpRbRBgQAAAAAYA5U1VTHHPm5JCcuDqqTpLv/LcmJSf7H1haxsxoAAAAAYA7MV/48le8m+fIS1788nrMkO6sBAAAAAObADryz+r1JHrXE9UeN5yxJWA0AAAAAMLDRCxZ32LD695PsVVX/WFUHV9UtxscDqurUJLcez1mSNiAAAAAAAHNgvvLnqVyZpJLcN8mjF13rzXMWB+zd/SObqYXVAAAAAACDm7vd0tN4U0Zh9XYRVgMAAAAAzIEdNazu7qeuxDrCagAAAACAObCDZtUrRlgNAAAAADCwqqQ2rO+0WlgNAAAAADAH7KwGAAAAAGBwtf3vKNyhCasBAAAAAObB+s6qhdUAAAAAAPOg1nkfkA1DFwAAAAAAAHZWAwAAAAAMrbxgUVgNAAAAADCwSq37NiDCagAAAACAObDOs2phNQAAAADAPLCzGgAAAACAwa3zrDobZv2AqtpQVUdV1YVVdV1Vfamqjq+q3ZZx752r6tiqOruqvlpV366q86vqucu5HwAAAABgh1CjndXTHGvNzMPqJK9M8ookn0ryjCRvT/LMJO+uqq09/7AkRyX5XJJjk/yvJBcleXGSs6rq5rMqGgAAAABgtVRGO6unOdaambYBqap7ZBRQn9rdj10w/vkkr0ry+CQnLbHEO5Ic191XLRh7bVVdnOS5SZ6a5NUrXjgAAAAAwCpbiwH0NGa9s/oJGf2hwAmLxl+X5Jokhyx1c3eftyio3uzk8fme21sgAAAAAMA8qCn/WWtmHVYflOSGJOcsHOzu65KcP76+LfYbn6/c5soAAAAAAObILNqAVNVzqurtVXVJVXVVXbqV+T9bVaeP3x/4rar6p6q6z/Z/d1s30zYgSfZJsqm7vzvh2mVJHlhVO3X395a7YFXdJMnzk/wgS7cQAQAAAADYYczopYkvSfL1JB9NsudWnv+AJGdklN0ePR4+MskHq+qB3X3BLArcbNZh9a5JJgXVSXLdgjnLDqszailycJI/7e6LlppYVUckOSJJds4eUzwCAAAAAGD1zPCliQd09yWjZ9Qnkuy+xNxXZZTVPqi7Lxvfc0qSTyc5Psn/M5MKx2bdBuSaJDtv4douC+YsS1W9KKMkf2N3H7e1+d29sbvv1933u1l2Xe5jAAAAAABWWaVqumM5NgfVW3161R0zatv89s1B9fj+y5K8PckvVNVttuEbW7ZZh9WXJ9mrqiYF1vtm1CJkWbuqq+qYJM9L8sYkv7NiFQIAAAAAzIFZ9Kyewub3C35owrWzk1SSA1f8qQvMOqw+d/yM+y8crKpdktwnyXnLWWQcVL8gyZuTHN7dvaJVAgAAAAAMbBY7q6ewz/h82YRrm8f2XemHLjTrsPrkJJ3k2YvGn5ZRr+q3bR6oqgOq6q6LF6iqozMKqt+a5LDuvmFm1QIAAAAADKWmPEZdLc5bcByxHU/f3Ed50jsIr1s0ZyZm+oLF7r6gql6T5MiqOjXJe5PcLckzk5yZ5KQF09+f5PbZ/K85SVU9PckLk3wxyelJnrjoTwyu7O73zfJ7AAAAAACYU5u6+34rtNbmdwtOauk89fsHt8VMw+qxZye5NMkRSR6ZZFOSE5McvYxd0pv7pNwuoxYgi52ZRFgNAAAAAOzYKrNo7TGNy8fnSa0+No9NahGyYmYeVnf39UmOHx9Lzdt/wtihSQ6dRV0AAAAAAPOiMpOXJk7j3PH54CSvX3TtARm1e/7ILAuYdc9qAAAAAACWYcgXLHb3Z5Ocl+RxVbX5ZYsZf/24JB/o7itW9KGLrEYbEAAAAAAAtmIWG6ur6kkZvSswSfZOslNVPW/8+Qvd/dYF05+V5F+TfLCqThyPPSOjTc9/MIPyfoSwGgAAAABgDsyoZ/VTkzx40diLxuczk/x3WN3dZ1XVQ5K8eHx0krOSPK67/3MWxS0krAYAAAAAmAOzyKq7+yFTzv9QkoevfCVbJ6wGAAAAABjYLPpQ72iE1QAAAAAAc2CdZ9XCagAAAACAeSCsBgAAAABgcNqAAAAAAAAwuHWeVQurAQAAAACGVmVn9YahCwAAAAAAADurAQAAAADmwHrfWS2sBgAAAACYA+s8q9YGBAAAAACA4QmrAQAAAAAYnDYgAAAAAABzYL23ARFWAwAAAADMgcr6TquF1QAAAAAA82B9Z9XCagAAAACAoVVpAyKsBgAAAAAYXGkDMnQBAAAAAABEG5ChCwAAAAAAYN1n1cJqAAAAAIB5UOu8abWwGgAAAABgHqzvrFpYDQAAAAAwD9Z5Vi2sBgAAAAAYWkUbkA1DFwAAAAAAAHZWAwAAAAAMrZJ1vrFaWA0AAAAAMA+0AQEAAAAAgIHZWQ0AAAAAMAfW+cZqYTUAAAAAwPAqldmk1VXVW7j0ne7efSYP3QbCagAAAACAte+DSTYuGvv+EIVsibAaAAAAAGAezLYNyCXd/XczfcJ2ElYDAAAAAAysMvue1VW1U5Kduvvq2T5p22wYugAAAAAAAMaB9RTHlH49yTVJvl1V/1VVJ1bVHitS+AqZeVhdVRuq6qiqurCqrquqL1XV8VW12zastWtVXVJVXVWvnkW9AAAAAACrbvPW6mmO5TsnyTEZBdZPSfKBJEcm+WBVrasXLL4yyTOT/GOS45Pcbfz5vlX1C919wxRrHZtk75UvEQAAAABgWNuwW3qvqjpvweeN3b34JYrp7p9dNPSWqvp4kj9L8qzxeXAzDaur6h5JnpHk1O5+7ILxzyd5VZLHJzlpmWv9TJJnJ/mjjEJvAAAAAIA1Yxt6Vm/q7vtt4+NeluQFSR6ZOQmrZ90G5AkZ/YHACYvGX5dRf5RDlrNIVd1kfM8/JTl1BesDAAAAAJgPs2sDciPd/f0klyfZa0VqXwGzDqsPSnJDRj1R/lt3X5fk/PH15TgqyV0z6qMCAAAAALDmzPgFiz/6rKpdkuyX5MrtXGrFzDqs3iejrejfnXDtsox6quy01AJV9VNJXpjk2O6+dOVLBAAAAAAY1qzer1hVt9rCpRdl1Cb63SvzHWy/Wb9gcdckk4LqJLluwZzvLbHGa5NckuQV0z68qo5IckSS7Jw9pr0dAAAAAGAVbe9+6YmeV1UPSPKvSb6YZPckv5zkoUk+nOTEWTx0W8w6rL4mya23cG2XBXMmqqpDkvxikgeNe6hMZfzmy41J8mO1T097PwAAAADAatnONtRbckaSuyd5SpJbJbk+ycVJnpvkFeOWzXNh1mH15UnuXlU7T2gFsm9GLUIm7qquqp0z2k393iRXVNUdF9yXJHuMxzZ19zdXvnQAAAAAgB1bd78zyTuHrmM5Zt2z+tzxM+6/cHDcvPs+Sc5b4t6bJ9k7ySMzSvo3H2eMrx8y/nz4ShYMAAAAALDqpuxXPaNd2IOa9c7qk5P8aZJnJ/nggvGnZdSr+m2bB6rqgCQ36+4Lx0PfSfK4CWvuneSvkvxTkjck+fiKVw0AAAAAsOrWYAI9hZmG1d19QVW9JsmRVXVqRi097pbkmUnOTHLSgunvT3L7jH9Fxj2q37F4zaraf/zl57r7RtcBAAAAAHZEa3G39DRmvbM6Ge2qvjTJERm19NiU0Rsmj+7uG1bh+QAAAAAAzLmZh9XdfX2S48fHUvP2X+Z6l2a974cHAAAAAFhjVmNnNQAAAAAAW7POt+gKqwEAAAAABlbjf9azDUMXAAAAAAAAdlYDAAAAAMyBWt8bq+2sBgAAAABgeHZWAwAAAAAMrbLut1YLqwEAAAAA5sD6jqqF1QAAAAAA82Gdp9XCagAAAACAObDOs2phNQAAAADAXFjnPas3DF0AAAAAAADYWQ0AAAAAMAfW975qYTUAAAAAwHxY52m1sBoAAAAAYGCVpNZ5Wi2sBgAAAACYB+s7qxZWAwAAAADMg3WeVWfD0AUAAAAAAEB199A1rIqq+mqSLwxdB6tqrySbhi4CmCk/57D2+TmHtc/POax9fs7Xn9t3995DF7GjOfDAA/us/zh7qnt2uflOH+nu+82opFW3btqA+AFZf6rqvLX0wwrcmJ9zWPv8nMPa5+cc1j4/5zCN9d0IZN2E1QAAAAAA82x9R9XCagAAAACA+bDO02phNWvZxqELAGbOzzmsfX7OYe3zcw5rn59zWKZ1nlVnw9AFwKx0t/8Ywhrn5xzWPj/nsPb5OYe1z885LFclNeWx3JWrNlTVUVV1YVVdV1Vfqqrjq2q3GX5DUxNWAwAAAACsba9M8ookn0ryjCRvT/LMJO+uqrnJiLUBAQAAAACYA1Nslp5izbpHRgH1qd392AXjn0/yqiSPT3LSyj95enOTmsP2qqrnVNXbq+qSquqqunTomoCVU1V3rqpjq+rsqvpqVX27qs6vqufO219bAlZOVe264L/trx66HmD7VdXuVfWnVXXB+L/nm6rqrKo6tGoWv0UHgHXvCRm1wz5h0fjrklyT5JDVLmhL7KxmLXlJkq8n+WiSPYctBZiBw5I8Pcm7krwtyfeTPDTJi5P8RlU9oLuvHbA+YDaOTbL30EUAK2P814z/b5IHJnlzkhOT7JrRb6LfmORuSf54sAIBYECVZEZ/bntQkhuSnLNwsLuvq6rzx9fngp3VrCUHdPetuvsXk1w+dDHAintHkv26+7e6+8Tufm13/2aSP0tyryRPHbY8YKVV1c8keXaSFwxcCrByfjbJ/0jyqu4+rLs3dvcJSX4+yeeT/PaQxQHAGrVPkk3d/d0J1y5LsldV7bTKNU1kZzVrRndfMnQNwOx093lbuHRykucmuecqlgPMWFXdJKO/lvhPSU5NcvywFQEr5Bbj849sLunu71XVpiQ7r35JADAfPvLRj/zzTW92k72mvG2Xqlr4++WN3b1x0Zxdk0wKqpPkugVzvjfls1ecsBqAHd1+4/OVg1YBrLSjktw1yWO3NhHYoZyT5JtJ/mj8jpkPZ/Sb46ckOTDJ7wxWGQAMrLsfMaOlr0ly6y1c22XBnMEJqwHYYY13Xj4/yQ8yJ28uBrZfVf1UkhcmOba7L62q/QcuCVgh3f2NqvqVJK9PcsqCS99O8tjuPm2QwgBgbbs8yd2raucJrUD2zahFyOC7qhM9qwHYsZ2Q5OAkR3f3RQPXAqyc1ya5JMkrhi4EmImrk3wiycuTPCbJ4Uk+m+SkqvrFIQsDgDXq3Ixy4PsvHKyqXZLcJ8mW2m6uOmE1ADukqnpRkiMz6sd13ND1ACujqg5J8otJfre7vz90PcDKqqqfTnJWkvd19//q7n/s7jdk9NLFK5K8bvw3pwCAlXNyks7o5eULPS2jdlxvW+2CtkRYDcAOp6qOSfK8JG+M3pawZlTVzhntpn5vkiuq6o5Vdccktx9P2WM8tudQNQLb7aiMemO+feFgd1+T5D0Z/bzvv/plAcDa1d0XJHlNksdU1alVdXhVHZ/R//c+M3PUVlNYDcAOZRxUvyDJm5Mc3t09bEXACrp5kr2TPDLJxQuOM8bXDxl/PnyI4oAVse/4PGn39E0XnQGAlfPsJH+Y5B4ZBdePT3Jikv+vu28YsK4fUX6Pz1pUVZ9Isnt37z90LcDKqaqjM3rp2luTHDpP/0EFtl9V3SzJoydc2jvJXyX5pyRvSPLx7v7MatYGrIyqemVGv1n+4+5+6YLxPZN8KqNd13t39/WDFAgADEpYzZpRVU/KD/+a8DOS7JTk+PHnL3T3WwcpDFgRVfX0JK9O8sUkz0+yOKi+srvft+qFATNXVfsn+XyS13T3kQOXA2yHqrp9ko8m+fGM+mP+R5JbZtQzc/8kT+/uvxqsQABgUMJq1oyqOiPJg7dw+czufsjqVQOstKp6U5KnLDHFzzmsUcJqWFuq6oAkRyd5eJKfSHJtkvOTnNDdpw5YGgAwMGE1AAAAAACD84JFAAAAAAAGJ6wGAAAAAGBwwmoAAAAAAAYnrAYAAAAAYHDCagAAAAAABiesBgAAAABgcMJqAAAAAAAGJ6wGAGAmqurSqjpjO+4/o6ouXbmKAACAeSasBgAAAABgcMJqAAAAAAAGJ6wGAAAAAGBwwmoAALZLVf1kVZ1SVVdV1beq6t1VdcAS83+hqv6lqr5ZVddV1cer6neW+az7V9WbquozVXVNVX27qv6jqn5t0by/rKquqjtNWOO2VfWDqvrb6b9bAABgVoTVAABss6raM8m/JXlMkrcm+ZMk1yT51yS7TZh/RJJ/SbJ7kj9L8vtJPpfkr6vqZct45K8luWuSU5I8a7zGLZOcWlVPXDDvdePzYRPWeEqSmyR5/TKeBwAArJLq7qFrAABgB1VVL0nynCSHdfcbF4yfkFGYfGZ3P2Q8dtskn09yanc/cdE6f5nkyCR36u5LxmNnJNm/u/dfMG+37v7Oont3TfKxJNd3990XjJ+VZP8kP9nd1y8Y/0ySHyycCwAADM/OagAAtsevJrkyyVsWjf/FhLm/nmTnJG+oqr0WHknendH/N/2FpR62MKiuql2r6lZJdk3ygSR3q6pbLJi+Mcltk/zygnselOROSd6wvG8PAABYLTcdugAAAHZod0hy7sKdy0nS3V+pqm8umnu38fn0Jdb7iaUeVlW3TvLiJI9OcusJU/ZM8q3x1ycnOSHJUzMKwzP++nu5cbgOAAAMTFgNAMBqqfH5yUm+soU5l2zx5qrKqN/13ZL8ZZLzklyV5Pok/zPJE7Pgbw5297VV9XdJfruqfiLJtRnt7n5Xd391+74VAABgpQmrAQDYHpckuVNV3WRRX+jbZrTLeaGLx+dN3b3U7uotuVeSeyc5trtfsPBCVR2+hXs2Jnl6Ri9VvCqjliFagAAAwBzSsxoAgO3xzoxadzx50fgfT5h7SpLvJnlhVd188cWq2qOqdl7iWZvD8Fo4WFX3TPJrk27o7o8nOSfJYRm1APliRruzAQCAOWNnNQAA2+OlGbXfeF1VHZjkk0kekuTgJJsWTuzuL1fV7yZ5fZJPV9Vbk3whyd5JfjqjlzXePcmlW3jWp8fr/1FV7ZrkoiR3TvLbSS5IcuAW7ts4fmaSvLC7b5j2mwQAAGZPWA0AwDbr7m9U1c8neUV+uLv6zCQPTfL+CfPfWFWfSfKHGYXMe2YUal+U5PlJrljiWddX1SOTvDyjth67JfnE+Ot7Z8th9f8e17d7kjdO9x0CAACrpbp76BoAAGBmxq1FvpLk3O7+f4euBwAAmEzPagAA1rrfSvLjGbUDAQAA5pSd1QAArElV9agkt09yTJIrk9yru69f8iYAAGAwwmoAANakqro0yT5JPpLk8O7+5LAVAQAASxFWAwAAAAAwOD2rAQAAAAAYnLAaAAAAAIDBCasBAAAAABicsBoAAAAAgMEJqwEAAAAAGJywGgAAAACAwf3//4wohKMHQd4AAAAASUVORK5CYII=\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/mnt/484A4CAB4A4C9798/GoogleDrive/Maestria-Drive/HiWi/mdp-playground/mdp_playground/analysis/analysis.py:566: UserWarning: FixedFormatter should only be used together with FixedLocator\n", - " plt.gca().set_xticklabels(tick_labels[0])\n" - ] - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABbEAAAFCCAYAAADPD5CEAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAAA1g0lEQVR4nO3de7hdVX3v//dnIyQGVGoDKqiAqAVvRQUqWu96erFWW9pToKgUAbUCktpq1XIRrfanRiiI1eANKXgQT7zQWm8o1J+KgJWCF0CBgAWhREXUEEDyPX/MmbLcrL2z1s5ee82svF8+85nZY44x1tjy7AfyyTffmapCkiRJkiRJkqQumhr3ASRJkiRJkiRJmokhtiRJkiRJkiSpswyxJUmSJEmSJEmdZYgtSZIkSZIkSeosQ2xJkiRJkiRJUmcZYkuSJEmSJEmSOute4z6AJEmSJEmSJG3u7p+H152sGWrNz/nhZ6vqd0d0pM4wxJYkSZIkSZKkMbuTNeyZQ4dac14dv3REx+kU24lIkiRJkiRJkjrLSmxJkiRJkiRJ6oIMOb9GcorOMcSWJEmSJEmSpDELkKkhU+x1IzlK5xhiS5IkSZIkSdK4BTJsJfZmwhBbkiRJkiRJkrrAFLsvQ2xJkiRJkiRJ6gAz7P6mxn0ASZIkSZIkSVLI1HDXQLsmr0tydpKrk1SSVXM6XfLiJN9McluSm5K8L8l2c9lrWIbYkiRJkiRJkjRuoSnFHuYazFuAZwFXAT+Z09GSZcBpwE+BVwHvBfYDzkuy9Vz2HIbtRCRJkiRJkiSpA0bUTmTXqrq62T/fArYZ7kxZCrwZuAh4dlXd1Y5fBHyKJtR+y7yeeJrNJsTeMktqMduO+xiSRuiBj7j/uI8gacRsDydNvpuunlNxkKRNyE6P2n7cR5A0YpdddsnqqlqQNhOTpCnEnv/f9awPsDfCC4ElwMnrA+x233OSXA0ciCH2/FjMtjyRQ8Z9DEkj9NqT/nzcR5A0YqP4DzpJ3XLin5097iNIGrH3fuovx30ESSO28y73v3bcZ9hkdfO3PHu196/1eXYBsH+Sbarq56M6wGYTYkuSJEmSJElSZ4WBX9a4wHZo79f3eXY9TfS+A3DlqA5giC1JkiRJkiRJHTCHv3y6NMnFPV+vqKoV83cioGklAnB7n2drp80ZCUNsSZIkSZIkSeqC4VPs1VW15yiO0mNNe18E3Dbt2eJpc0ZiapSbS5IkSZIkSZIGkwx3LZAb2vuOfZ7tCFTPnJEwxJYkSZIkSZKkcUvI1HDXArmove/T59mTgCtG+VJHMMSWJEmSJEmSpG4Ycyl2kocm2S3Jlj3Dn6RpI3J4ki165j4feBhwxrwfZBp7YkuSJEmSJEnShEryImCn9svtgK2S/F379bVVdXrP9A8DTwd2AVYBVNXNSY4G3gF8IclHaNqIvBq4HDhx1N+DIbYkSZIkSZIkjVkYWZ/rl9IE073e1N7PB05nA6pqeZIfAcuAk4BbgY8CfzvqViJgiC1JkiRJkiRJnZARpNhV9Yz5mFtVHwI+tNEHmgNDbEmSJEmSJEnqggV7V+OmxRBbkiRJkiRJksYtkClT7H4MsSVJkiRJkiSpC8yw+zLEliRJkiRJkqQOGEVP7ElgiC1JkiRJkiRJYxdD7BkYYkuSJEmSJEnSuAWYGvchuskQW5IkSZIkSZLGLNhOZCaG2JIkSZIkSZLUAWbY/S1IgXqSFyf5ZpLbktyU5H1JtpvjXlNJvpakkvzLfJ9VkiRJkiRJksYiGe7aTIw8xE6yDDgN+CnwKuC9wH7AeUm2nsOWfwk8Zv5OKEmSJEmSJEljNmR+vRll2KNtJ5JkKfBm4CLg2VV1Vzt+EfApmlD7LUPs9+B2/rHA8nk/sCRJkiRJkiSNSaY2o2R6CKOuxH4hsAQ4eX2ADVBV5wBXAwcOud8p7bp/nK8DSpIkSZIkSVInWIrd16hf7LhXe/9an2cXAPsn2aaqfr6hjZL8CfB84MlVdZdv6pQkSZIkSZI0KcJmlUsPZdSV2Du09+v7PLue5p/NDn2e/Yok9wNOAt5bVRfM3/EkSZIkSZIkqQMSMuS1uRioEjvJtsBRQ+x7UlX9mKaVCMDtfeasbe9L+jyb7m00gfvrhjgDSQ4DDgNYxP2GWSpJkiRJkiRJ6oBB24lsS/MyxUH9M/BjYE379SLgtmlzFrf3NcwiyVOBQ4EXVdUtQ5yBqloBrAC4T3aoYdZKkiRJkiRJ0oIadd+MTdRAIXZVraJp/TGsG9r7jsD3pz3bEaieOTN5F/CfwNeTPHzasyXt2C1VtXoO55MkSZIkSZKkTticWoQMY9TZ/kXtfZ8+z54EXDHASx13AvYAvjftAnhm++vjNvagkiRJkiRJkjRO9sTub9B2InP1SZoXMh6e5MyqugsgyfOBhwFH905O8lCaHtlXVdWd7fCLga367H028A3gH7hnlbckSZIkSZIkbToCsZ1IXyMNsavq5iRHA+8AvpDkIzRtRF4NXA6cOG3Jh4GnA7sAq9o9PtVv7/ZPGm6sqo+N4uySJEmSJEmStKA2o+rqYYy6EpuqWp7kR8AymqrsW4GPAn87QCsRSZIkSZIkSZp4wQx7JiMPsQGq6kPAhwaY94wh9vQfqSRJkiRJkqTJEMiUkWc/CxJiS5IkSZIkSZJmE0uxZ2CILUmSJEmSJEkdYIbdnyG2JEmSJEmSJHWA7UT6M8SWJEmSJEmSpHHzzY4zMsSWJEmSJEmSpA4ww+7PEFuSJEmSJEmSxizYTmQmhtiSJEmSJEmS1AVm2H0ZYkuSJEmSJEnSuAViP5G+DLElSZIkSZIkaexiO5EZGGJLkiRJkiRJUgdYiN3f1LgPIEmSJEmSJEnSTKzEliRJkiRJkqQusBS7L0NsSZIkSZIkSRq3YE/sGRhiS5IkSZIkSdKYBQuxZ2KILUmSJEmSJEldYIrdlyG2JEmSJEmSJHVADLH7mhr3ASRJkiRJkiRpsxfI1HDXwFsnU0mWJbk8ydokP0iyPMnWA67fJsnrk1yW5GdJVif5apKDsgDJu5XYkiRJkiRJkjR2GWU7kROAI4GPA8uB3duvH5/kOVW1bsZTJVPAvwFPBk4DTgaWAPsDH2z3eu2oDg6G2JIkSZIkSZLUCaPIsJM8GjgCWFlV+/aMXwOcBOwHnDnLFr8F/DZwYlUt61n/buBy4GWMOMS2nYgkSZIkSZIkjVsgUxnqGtD+ze6cOG38VGANcOAG1t+3vd/QO1hVdwCrgV8MepC5shJbkiRJkiRJkrpgNO1E9gLWARf2DlbV2iSXtM9ncyFwC/CaJKuAr9O0E3kJ8ETg5dMXJHn6sIesqvNnemaILUmSJEmSJEljFkbWEnsHYHVV3d7n2fXAk5Ns1VZW30NV/STJHwLvAz7a8+hnwL5V9Yk+y75I8y0NY8auIYbYkiRJkiRJktQBQ7QIWW9pkot7vl5RVSumzVkC9AuwAdb2zOkbYrd+DnwL+BTwVeD+wCuBM5O8oKo+P23+X3PPEPsRwGHAsTRtTNZ7AnDALJ9tiC1JkiRJkiRJY5fMpRR7dVXtuYE5a4DtZ3i2uGfODMfKY2mC62VV9Z6e8Y/QBNunJtm1qu5a/6yqTuizz7NoXgL5T1X1o57xA9hAiO2LHSVJkiRJkiSpA9bn2INeA7qBpmJ7UZ9nO9IE4bNVYS+jCbvP7h2sqjXAvwI7ATsPcI4t2/v0k2/wOzHEliRJkiRJkqQOyFSGugZ0EU0OvPevfFayGNgDuLjPml47tvct+jy717T7bB7b3h84bfyBwC9mW2iILUmSJEmSJEnjFkgy1DWgs4ACjpo2fihNL+wz/ucIya5Jdps27zvt/aBfOW6yLfAC4CfA92f91pJ9gNe2X76iZ3wJ8GLgytnW2xNbkiRJkiRJkiZUVV2W5BTg8CQrgU8DuwNHAucDZ/ZMP5emPUhvQn4iTdD8D21/7K/QvNjxUOBBwCt7+2H3SrIrcDTwIuBC4DzgFW2o/X3gScCDgb+a7XswxJYkSZIkSZKkLhj6vY4DOwpYBRwGPA9YDZwMHFNV62ZbWFXXJtkbOAZ4NrAfcBtwCfDqqlo5fU1bzf2Gdu4UTTX4y2l6a+8I/BbwmzQV4ivas8zIEFuSJEmSJEmSxiwwTJ/robSV0svba7Z5O88wfhXwkiE+8jKa8PpcmqD8gnb8VuDJSR5OU819VVX9aEObGWJLkiRJkiRJUgcM0ee66/6dJrz+Sr+HVTVrD+3pDLElSZIkSZIkadwSGFEl9kKrqmev/3WS+wMPp2kdckVV3TrsflPzeDZJkiRJkiRJ0hwlw11dluTBSc4BbgYuAL4O/DjJJ5M8ZJi9DLElSZIkSZIkqQOSDHV1VVt9/WXgfwEfBU6nqcT+AM1LHS9I8sBB9zPEliRJkiRJkqRxC007kWGu7notsAPwtKraHziN5jt8HfB4mjbXxw66mT2xJUmSJEmSJKkDOlxcPawXAB+uqq9Pf1BVP0zyfuDPB91sQSqxk7w4yTeT3JbkpiTvS7LdgGt3TPK6JOcn+WGSXyT5dpK3J/n1UZ9dkiRJkiRJkkYtQKYy1NVhDwW+Ocvzq4DutBNJsoymXPynwKuA9wL7Aecl2XqALZ4PHAf8CHg7cBTw1fZ+yTC9UyRJkiRJkiSpsybnzY5rmT17fjiwetDNRtpOJMlS4M3ARcCzq+qudvwi4FM0ofZbNrDNl4GdqurGnrFTk3wdOBX46/aSJEmSJEmSpE1Tx1/WOKQfAA/rM54kTwD+Evg/g2426krsFwJLgJPXB9gAVXUOcDVw4IY2qKpvTwuw1zurvT9mHs4pSZIkSZIkSWOVqeGuDjuXpi92r6IpWP46cCPwd4NuNuoXO+7V3r/W59kFwP5Jtqmqn89h7we395vmdDJJkiRJkiRJ6pAJqsReAdySZGlVrQZuoylq/hHwEeCEqvrZoJuNOsTeob1f3+fZ9TT9yncArpzD3m9s76fNYa0kSZIkSZIkdcuEhNhVdTlwfM/XXwMeMdf9Bgqxk2xL8yLFQZ1UVT+maSUCcHufOWvb+5I+zzZ0nlcDfwqsqKovzjLvMOAwgEXcb9iPkSRJkiRJkqSFkc63CJk3SbYE9qmqfx9k/qCV2NsCxw5xjn8Gfgysab9eRFMy3mtxe1/DEJIcArwd+Ffg8NnmVtUKmtJ17pMdapjPkSRJkiRJkqSFEiaqncivSDIF7Ak8q72eAtybAd/ZOFCIXVWraP5/HNYN7X1H4PvTnu1I08z7BgaU5GCaUPpzwL5VdeccziRJkiRJkiRJGqEkj+Pu0PppwH1p8uDrgY8BM3bYmG7UPbEvomnnsQ/3DLGfBFwx6Esd2wD7fcAXgBdWVb8WJZIkSZIkSZK0aZqajErsJP8NLG2/XA18lia0/mJVfW/Y/UbdZeWTNG1EDk+yxfrBJM8HHgac0Ts5yUOT7Nb2ROkdPwg4leYbfUFVrUWSJEmSJEmSJkVChrw67P40VdffBY4GXl9V751LgA0jrsSuqpuTHA28A/hCko/QtBF5NXA5cOK0JR8Gng7sAqwCSPKHwPuBW4GzgH2n/QP6eVV9YmTfhCRJkiRJkiQtgG7n0kN5One3EjkRWJTkOuBL3F2Rff2gm426nQhVtTzJj4BlwEk0YfRHgb8dsJXIE2gqxrelfUnjNNcCn5iXw0qSJEmSJEnSuExIO5Gq+grwFeBNSRbTvMjxWcCzgT8H7pXke1X1G4PsN/IQG6CqPgR8aIB5z+gzdhxw3DwfSZIkSZIkSZI6peMtQuakbQ19bpL/AC4G9gX+DHjEoHssSIgtSZIkSZIkSZpFJqqdCEm2Bp7G3RXYvwkE+A7wbpq2IgMxxJYkSZIkSZKkLpiQdiJJ/n9gb5r8eRVNYP12ml7YNw27nyG2JEmSJEmSJI1ZmKh2Ivtwd9X1B2he6HhJVdVcNjPEliRJkiRJkqRxS8iEVGIDh9K0EHkmTQV2gB8n+XeaQPvcqvrOoJsZYkuSJEmSJElSF0xIhl1VH6CpwCbJ7jR9sZ8FPB14QTOc/66qBw6ynyG2JEmSJEmSJHXABLUT+R9V9V3gu8ApAEkeT1Oh/exB9zDEliRJkiRJkqQOmKB2IjOqqm8C3wTeOegaQ2xJkiRJkiRJGrdMViV2kilgd2CLqrp0Y/aamp8jSZIkSZIkSZI2Soa8OirJQ4D/BC4DLklySZLt2mf3TvKWJHsNup8htiRJkiRJkiSNWWgqsYe5OuwdwK7A8cBxwG8Afw9QVbcBzwD+ctDNbCciSZIkSZIkSR3Q7Vx6KM8ATqmq46Cpvgb+Ajisff4F4M8G3cxKbEmSJEmSJEnSfNoauKLn628A27dhNsC1wIMH3cxKbEmSJEmSJEnqgAmqxP4WTQuR9X7a3u8N3Ab8OnDXoJtZiS1JkiRJkiRJ4zZkP+yO98R+K3BYkse0X68PrKeSLAZeAlw66GZWYkuSJEmSJElSB3Q7lx7KHjTtRC5O8gngl+348cCzgEcCfzzoZobYkiRJkiRJkjRmga5XVw/jmJ5f/2l7L+BlwHeBA6rqE4NuZogtSZIkSZIkSR0wORk2u/QZWwfcUlU/H3Yze2JLkiRJkiRJUgeMqid2kqkky5JcnmRtkh8kWZ5k6yH2uH+SdyT5frvHzUm+lOSp0+dW1XV9rv+aS4ANVmJLkiRJkiRJ0vhlpJXYJwBHAh8HlgO7t18/PslzqmrdrEdLdgLOA7YB3g9cCdwPeByw48hO3TLEliRJkiRJkqQOCPOfYid5NHAEsLKq9u0ZvwY4CdgPOHMD2/wzTZb8uKr64QCf+cFBjlZVBw0wzxBbkiRJkiRJksatebHjSLbev93+xGnjpwL/ABzILCF2kqcBvw0cWVU/TLIlsGVVrZnlM1/UfmbfLWle8hjgoAHOb09sSZIkSZIkSeqCZLhrQHvRvFTxwt7BqloLXNI+n83vt/frkpwD3Ab8IsmVSQ7st6Cq7lVVW/RewNbAHsDpwKXA9oN+A4bYkiRJkiRJktQBI3qx4w7A6qq6vc+z64GlSbaaZf1vtPdTgfsDLwEOBu4ATk/yF4McoqrWVtVlVfUS4IfA2wb9BmwnIkmSJEmSJEkdMId2IkuTXNzz9YqqWjFtzhKgX4ANsLZnzh0zzLlPe/8Z8MyquqM5az4BXA28JclpG3o55DT/Ahwz6GRDbEmSJEmSJEkatyF7hLRWV9WeG5izhplbdyzumTOT29r7R9YH2ABV9ZMknwJeTFOt/d0Bzrve1jQB/OK2rcmsbCciSZIkSZIkSR0wop7YN9AExov6PNuRJgifqQob4L/a+419nv2wvf/aTIuTTCV5QHutP/X7gYcBd85+9IYhtiRJkiRJkiSNWRhZT+yLaHLgvX/l85LFNC9avLjPml7rXwj54D7P1o/99z2+n+RhSc4EbqEJu38I/LQdu29VXVdVdw3yDRhiS5IkSZIkSVIHjKgS+yyggKOmjR9K0wv7jLs/P7sm2W3avE/Q9MM+MMk2PXMfBLwQuLKqvv+r30ceDXwD+DOaNiOnt9d327H/aOcMxJ7YkiRJkiRJkjShquqyJKcAhydZCXwa2B04EjgfOLNn+rnATjSF4evX/yTJXwPvBS5I8gFgK+AV7f2IPh+7HNgSeFZVnd/7IMnTgH9t5/zuIN+DIbYkSZIkSZIkdcAQLUKGdRSwCjgMeB6wGjgZOKaq1m1ocVWtSLIaeA3wJmAd8DXggKr6Sp8lTwFOnh5gt3v9e5KTaUL0gRhiS5IkSZIkSdK4DdciZCht7+nl7TXbvJ1nebYSWDngR97O3S+E7Oe/2jkDsSe2JEmSJEmSJHVAhrw67NPA82d5/vx2zkAMsSVJkiRJkiRpzELTTmSYq8P+Clia5ONJ9kly3/Z6UtuXe/t2zkBsJyJJkiRJkiRJHdDtXHooN9Hk8o8HXjDtWa2fMz2Ir6q+RdeG2JIkSZIkSZLUAR2vrh7Gh5jHjieG2JIkSZIkSZLUAZOSYVfVS+dzvwXpiZ1kKsmyJJcnWZvkB0mWJ9l6IdZLkiRJkiRJUqcN2Q97gqq2N2ihXux4AvBO4DvAEcDZwJHAOUkGOcPGrpckSZIkSZKkzmpe7DjctbkYeTuRJI+mCZ5XVtW+PePXACcB+wFnjmq9JEmSJEmSJG0KNqdgehgLUcW8P80fJJw4bfxUYA1w4IjXS5IkSZIkSVLn2U6kv4V4seNewDrgwt7Bqlqb5JL2+SjXS5IkSZIkSVLnbUa59FAWohJ7B2B1Vd3e59n1wNIkW41wvSRJkiRJkiR1W6zEnslChNhLgH4BNMDanjnzvj7JYUkuTnLxnazZ4EElSZIkSZIkaWwy5LWZWIgQew2waIZni3vmzPv6qlpRVXtW1Z5bzpqTS5IkSZIkSdL4hMmpxE7ynCSXJXlOn2dPSvIvSb6b5Jwke25ov4XoiX0D8Kgki/q0BNmRplXIHSNcL0mSJEmSJEmd1+VgekgvAH4d+FLvYJJHA+cBWwI/Ah4JPCvJY6rqmpk2W4hK7Ivaz9m7dzDJYmAP4OIRr5ckSZIkSZKkzkuGuzrst4FPVdVd08ZfDWwF/ElVbQ/8Jk0r6dfNttlChNhnAQUcNW38UJpe1mesH0iya5Ld5rpekiRJkiRJkjR2OwKX9Rn/PeB7VfVxgKr6FvBh4KmzbTbydiJVdVmSU4DDk6wEPg3sDhwJnA+c2TP9XGAnetqSD7lekiRJkiRJkjY9He9zPaRtmfYewyQPAbanyXd7fZumYHlGC9ETG5oq6lXAYcDzgNXAycAxVbVuAdZLkiRJkiRJUmc1L3Yc9ynmzU+Bh0wbe3p7v2ja+L1pWorMaEFC7Lb3yfL2mm3ezhuzXpIkSZIkSZI2VRNUiX0pcECSt1fVbe3YITRZ/XnT5j4CuHG2zRaqEluSJEmSJEmSNIsJCrE/DHwAuDDJZ4HfAp4CfLmqLp82938BX5ttM0NsSZIkSZIkSRq3TE47kao6LcnTgZcAj2qHLwMO6p2XZHvgs8DK2fYzxJYkSZIkSZKkDpigSmyq6uAky2lC7OuBC6vql9Pm/Ddw5Ib2MsSWJEmSJEmSpDELkKnJCbEBqurbwLenjydZAmxXVdcOss/UfB9MkiRJkiRJkjS8ZLhrE/ZC4JpBJxtiS5IkSZIkSdK4JWTIq6uSPDzJ55LcmmTd9Av4Z6B6xo6dbT/biUiSJEmSJElSB3Q4lx7Wu4AnA18Aftzn+cOApwEfar++ZLbNDLElSZIkSZIkqQO6XF09pCcBx1fV2/o9THIA8LSqOniQzQyxJUmSJEmSJGnMwkSF2PcBrpuvzQyxJUmSJEmSJKkDJifDBqA28vn/MMSWJEmSJEmSpHFrSrHHfYp5UVVbbOD5mcCZg+5niC1JkiRJkiRJHTBB7UQASPIbwB/SvMgR4Grgk1V15TD7GGJLkiRJkiRJUgdMUoad5CTglX0e/UOSk4FlVTVQS5GpeT2ZJEmSJEmSJGmzluR1NAH2F4E/AB7eXs8DzgWOBP520P2sxJYkSZIkSZKksQuZmphS7MOALwO/U1XresavSfJZmiD7UOCtg2xmJbYkSZIkSZIkjVky/NVhDwT+77QAG4C2hchK4EGDbmYltiRJkiRJkiR1wAS92PF7wANmeb59O2cgVmJLkiRJkiRJUgckGerqsLcCr0zyhOkPkuwBHA78w6CbWYktSZIkSZIkSR3Q7Vx6KI8ErgIuTHIu8O12/FHAc4FLgEckObZnTarquH6bGWJLkiRJkiRJUgeMqro6yRTwKuBlwM7AzcBHgWOq6hdD7rUE+BawC3BKVR3eZ9oxPb9+Tnv12qO9fmVr4Lh+n2mILUmSJEmSJElj1ryscWSl2CcARwIfB5YDu7dfPz7Jc/q9gHEWxwPbbWDOLnM65QwMsSVJkiRJkiSpA0aRYSd5NHAEsLKq9u0ZvwY4CdgPOHPAvZ4AHAW8hiYM76uqrtuII9+DL3aUJEmSJEmSpLEb7qWOQ1Rt70/TquPEaeOnAmuAAwc6XbJFu+YzwMpBP3w+WIktSZIkSZIkSR0wonYiewHrgAt7B6tqbZJL2ueDWAbsBuy7oYnzzUpsSZIkSZIkSeqApi/24NeAdgBWV9XtfZ5dDyxNstXs58ouwBuB46tq1RDf0rywEluSJEmSJEmSxiyBTA1dib00ycU9X6+oqhXT5iwB+gXYAGt75twxy+e8B7gaeOewB5wPhtiSJEmSJEmS1AFz6Cayuqr23MCcNcD2Mzxb3DNnhjPlQOC5wNOq6s6hTzgPDLElSZIkSZIkqQPCSHpi3wA8KsmiPi1FdqQJwvtWYSdZRFN9/WngxiQP71kHcL92bHVV3TL/R2/YE1uSJEmSJEmSuiBDXoO5iCYH3vtXPipZDOwBXNxnzXr3BrYDngd8r+c6r31+YPv1IQOfZg6sxJYkSZIkSZKkDsgc+okM4Czg9cBRwJd7xg+l6YV9Rs/n7wpsWVWXt0O/AP60z57bAe8GPgO8H7i092GSLw15xlTVM2Z6aIgtSZIkSZIkSROqqi5LcgpweJKVNK1BdgeOBM4HzuyZfi6wE22dd9sD+2PT90yyc/vLq6rqHs+Bp9G8TPKXAxzxXtzdm3vGCZIkSZIkSZKkccqcXuw4qKOAVcBhNK1BVgMnA8dU1boRfeahVXXGhiYl2Z+eavB+DLElSZIkSZIkacxCRtVOhKq6C1jeXrPN23nA/VYxTFfu2W1wH0NsSZIkSZIkSeqAEVZiL7TbgS0HnLsVcNtsEwyxJUmSJEmSJKkDRlWJPQY/AR4w4NwHALfMNsEQW5IkSZIkSZI6YHIybL4DPGXAuU9p589oaqOPswFJppIsS3J5krVJfpBkeZKtB1j7yCTHJ7kgyc1JfpbkkiRvGGS9JEmSJEmSJG0S0lRiD3N12OeB30vy2NkmJXk08LvAF2ebN/IQGzgBeCdNmn4EcDZwJHBOkg19/sHAMuAq4Hjgb4ArgDcDX01y71EdWpIkSZIkSZIWSmgqsYe5OuxDwC+ATyd5Tr8JSZ4N/BtNP+wPzLbZSNuJtEn6EcDKqtq3Z/wa4CRgP+DMWbb4GPDWqvppz9h7knwPeAPwUuBd835wSZIkSZIkSVpgHQ+mB1ZV/53kpTTZ7+eSXAtcCtwK3Bd4HLATcCfw4qq6abb9Rl2JvT/NHyKcOG38VGANcOBsi6vq4mkB9npntffHbOwBJUmSJEmSJKkLMuT/uqyq/i/wVOBzwIOAPwAOaO87AF8AnlFVZ824SWvUL3bcC1gHXNg7WFVrk1zSPp+LB7f3WRN6SZIkSZIkSdpUTEol9npVdSHwu21b6IfRVGHfClxdVbcNus+oQ+wdgNVVdXufZ9cDT06yVVXdMeiGSbYAjgZ+yeytSCRJkiRJkiRpk9HxlzXOWRtYf3uu60cdYi8B+gXYAGt75gwcYtO0JtkHeH1VXTHbxCSHAYcBLOJ+Q3yEJEmSJEmSJC2cTeBljUNLsiPwv4FHAAVcDpxdVTcOs8+oQ+w1wPYzPFvcM2cgSd4EHA6sqKq3bmh+Va0AVgDcJzvUoJ8jSZIkSZIkSQsrE1WJneQg4J+ArdYP0QTZb0vyqja7HcioX+x4A7A0yaI+z3akaTUyUBV2kuOAvwM+CLx83k4oSZIkSZIkSR2wvhp70KurkuwDnAr8J/D7wIvaR88BPgb8U5LnDLrfqEPsi9rP2Lt3MMliYA/g4kE2aQPsY4HTgEOqyqpqSZIkSZIkSRMlyVBXh/018F/AM6rqs8D69iGXVtWLgK8BfzPoZqMOsc+iKRE/atr4oTS9sM9YP5Bk1yS7Td8gyTE0AfbpwMFVtW5kp5UkSZIkSZKkccmQV3c9BTi9qtbO8PzjTCt8ns1Ie2JX1WVJTgEOT7IS+DSwO3AkcD5wZs/0c4Gd6Pm/P8krgTcC1wFfAA6Y9icMN1XV50f5PUiSJEmSJEmShrItcO0sz3/B3e9M3KBRv9gRmirsVcBhwPOA1cDJwDEDVFXv1d4fStNKZLrzAUNsSZIkSZIkSZu20PUWIcNYDWw3y/PnAlcOutnIQ+yqugtY3l6zzdu5z9hBwEGjOJckSZIkSZIkdUXo9ssah3QF8Lg+449P8gfAHwGvGHSzhajEliRJkiRJkiRtwARVYp8DvDnJfavq1nasgM8BdwFvr6r3DrqZIbYkSZIkSZIkdcDERNjwbmAlsP7FjlcDxwA3AV+oqlXDbGaILUmSJEmSJEkdMCmV2FV1B3Bdz9ergL+f635T83AmSZIkSZIkSdJGSoa7NkVJfi3JK5J8fdA1VmJLkiRJkiRJ0pglmZhK7OmSbAH8HvAS4PnAlsDNg643xJYkSZIkSZKkDpi0DDvJHjTB9QHAdsBtwCeADwOfGXQfQ2xJkiRJkiRJ6oBJCbGT/BVNeP2YdugrwBuAj1bVrcPuZ4gtSZIkSZIkSR0wQe1E3g78DDgeOK19seOcGWJLkiRJkiRJUgdMTobNXcB9gP2AXyY5vaqum+tmU/N2LEmSJEmSJEnSnCR3v9xx0KvDdgFeBxRNNfY1Sb6U5C+SbDPsZobYkiRJkiRJkqR5U1XXV9XbqupRwJOAdwOPBd4H3JjkjCS/M+h+htiSJEmSJEmS1AETVIn9P6rqoqo6AnggsC/weeBPgH8bdA97YkuSJEmSJElSB2wiufScVNUvgU8An0iyFDhg0LWG2JIkSZIkSZKkeZPkJe0vP15Vt05/XlWrgZMG3c8QW5IkSZIkSZI0nz4ABLgAuEeIPSxDbEmSJEmSJEnqgAlqJ3IcTYi9ej42M8SWJEmSJEmSpA4Ik5FiV9Wb5nM/Q2xJkiRJkiRJ6oLJyLDnnSG2JEmSJEmSJI1ZMlHtROaVIbYkSZIkSZIkjV0mpp3IfJsa9wEkSZIkSZIkSTTtRIa5Bt02mUqyLMnlSdYm+UGS5Um2HmDtI5Mcn+SCJDcn+VmSS5K8YZD188EQW5IkSZIkSZI6YEQZNsAJwDuB7wBHAGcDRwLnJNlQRnwwsAy4Cjge+BvgCuDNwFeT3Hu4owzPdiKSJEmSJEmS1AEZQVPsJI+mCa5XVtW+PePXACcB+wFnzrLFx4C3VtVPe8bek+R7wBuAlwLvmveD97ASW5IkSZIkSZK6YDSl2Pu3s0+cNn4qsAY4cLbFVXXxtAB7vbPa+2MGPskcWYktSZIkSZIkSR0wotc67gWsAy7sHayqtUkuaZ/PxYPb+01zP9pgrMSWJEmSJEmSpDELTTuRYa4B7QCsrqrb+zy7HliaZKuhzppsARwN/JLZW5HMCyuxJUmSJEmSJGnTtDTJxT1fr6iqFdPmLAH6BdgAa3vm3DHE554I7AO8vqquGGLdnBhiS5IkSZIkSdK4BebwXsfVVbXnBuasAbaf4dninjkDSfIm4HCawPytg67bGIbYkiRJkiRJktQBQ7QIGcYNwKOSLOrTUmRHmiB8oCrsJMcBfwd8EHj5vJ5yFvbEliRJkiRJkqTJdRFNDrx372CSxcAewMV91txDG2AfC5wGHFJVNa+nnIUhtiRJkiRJkiR1QDLcNaCzgAKOmjZ+KE0v7DPu/vzsmmS3e54rx9AE2KcDB1fVuuG/u7mznYgkSZIkSZIkjV0I899OpKouS3IKcHiSlcCngd2BI4HzgTN7pp8L7AR3HyTJK4E3AtcBXwAOmNb25Kaq+vy8H7yHIbYkSZIkSZIkTbajgFXAYcDzgNXAycAxA1RV79XeH0rTSmS68wFDbEmSJEmSJEmaeCN5ryNU1V3A8vaabd7OfcYOAg4axbkGZYgtSZIkSZIkSWMWhupzvVkxxJYkSZIkSZKkDjDD7m9q1B+QZCrJsiSXJ1mb5AdJlifZeg57LUlydZJK8q5RnFeSJEmSJEmSFtz6Uuxhrs3EyENs4ATgncB3gCOAs2nefHlOkmE//3hgu/k9niRJkiRJkiSNX4a8NhcjbSeS5NE0wfXKqtq3Z/wa4CRgP+DMAfd6As1bNF/DBhqQS5IkSZIkSdKmZjMqrh7KqCux96f5Q4ETp42fCqwBDhxkkyRbtGs+A6ycx/NJkiRJkiRJUjfYTqSvUb/YcS9gHXBh72BVrU1ySft8EMuA3YB9NzRRkiRJkiRJkjZFm08sPZxRV2LvAKyuqtv7PLseWJpkq9k2SLIL8Ebg+KpaNf9HlCRJkiRJkqTx8r2OMxt1JfYSoF+ADbC2Z84ds+zxHuBqmpdDDiXJYcBhAIu437DLJUmSJEmSJGkBbUbJ9BBGHWKvAbaf4dninjl9JTkQeC7wtKq6c9gPr6oVwAqA+2SHGna9JEmSJEmSJC2Uzam6ehijbidyA03LkEV9nu1I02qkbxV2u+adwKeBG5M8PMnDgZ3aKfdrx7YdwbklSZIkSZIkSR0w6hD7ovYz9u4dTLIY2AO4eJa19wa2A54HfK/nOq99fmD79SHzeWBJkiRJkiRJWnBD9sPenKq2R91O5Czg9cBRwJd7xg+l6YV9xvqBJLsCW1bV5e3QL4A/7bPndsC7gc8A7wcunfdTS5IkSZIkSdKC24yS6SGMNMSuqsuSnAIcnmQlTWuQ3YEjgfOBM3umn0vTKiTt2juBj03fM8nO7S+vqqp7PJckSZIkSZKkTdHmVF09jFFXYkNThb0KOIymNchq4GTgmKpatwCfL0mSJEmSJEnaRI08xK6qu4Dl7TXbvJ0H3G8V1tVLkiRJkiRJ0mZhISqxJUmSJEmSJEkbYuluX4bYkiRJkiRJkjRmaf+ne5oa9wEkSZIkSZIkSZqJldiSJEmSJEmS1AGxELsvK7ElSZIkSZIkSZ1lJbYkSZIkSZIkjVuwFHsGhtiSJEmSJEmS1AFG2P0ZYkuSJEmSJElSF5hi92WILUmSJEmSJEkdYIbdnyG2JEmSJEmSJHWBPbH7mhr3ASRJkiRJkiRJmomV2JIkSZIkSZLUAdZh92eILUmSJEmSJEldYIrdlyG2JEmSJEmSJI1ZgJhi92WILUmSJEmSJEldYIbdlyG2JEmSJEmSJHWAGXZ/U+M+gCRJkiRJkiRJM0lVjfsMCyLJzcC14z6HFtRSYPW4DyFppPw5lyafP+fS5PPnXJp8/pxvfnaqqu3GfYhNzROf+MT66lcuGGrN4ntv9Y2q2nNER+qMzaadiD84m58kF28OP8TS5syfc2ny+XMuTT5/zqXJ58+5NAwbivSz2YTYkiRJkiRJktRlRtj9GWJLkiRJkiRJUheYYvdliK1JtmLcB5A0cv6cS5PPn3Np8vlzLk0+f86lAZlh9zc17gNIo1JV/ktSmnD+nEuTz59zafL5cy5NPn/OpUEFMuQ16M7JVJJlSS5PsjbJD5IsT7L1QqzfWIbYkiRJkiRJkjTZTgDeCXwHOAI4GzgSOCfJIBnxxq7fKLYTkSRJkiRJkqQOGKK4eog982ia4HllVe3bM34NcBKwH3DmqNbPByuxNTGSvC7J2UmuTlJJVo37TJLmT5JHJjk+yQVJbk7ysySXJHnDQv31JUkLL8mSnn+3v2vc55G08ZJsk+T1SS5r/32+OslXkxyUjOK37pIkbfb2p2m3feK08VOBNcCBI16/0azE1iR5C/Bj4D+Abcd7FEkjcDDwSuBTwBnAncAzgTcD/zvJk6rqtjGeT9JoHA9sN+5DSJof7V83/jfgycBpwMnAEprfHH8Q2B147dgOKEnSGAUY0Z/n7gWsAy7sHayqtUkuaZ+Pcv1GsxJbk2TXqvr1qnoucMO4DyNp3n0MeHBV/XlVnVxV76mqPwP+Hngc8NLxHk/SfEvyBOAo4NgxH0XS/Pkt4LeBk6rq4KpaUVUnAk8FrgFeNs7DSZI0oXYAVlfV7X2eXQ8sTbLVCNdvNCuxNTGq6upxn0HS6FTVxTM8Ogt4A/CYBTyOpBFLsgXNX0/8DLASWD7eE0maJ/dt779SdFJVdyRZDSxa+CNJktQN3/iPb3z2XltusXTIZYuT9P5+eUVVrZg2ZwnQL4AGWNsz544Z5mzs+o1miC1J2tQ9uL3fNNZTSJpvy4DdgH03NFHSJuVC4BbgNe07bL5O85velwBPBF4+tpNJkjRmVfW7I9p6DbD9DM8W98wZ1fqNZogtSdpktZWaRwO/ZMRvQpa0cJLsArwROL6qViXZecxHkjRPquonSf4QeB/w0Z5HPwP2rapPjOVgkiRNthuARyVZ1KclyI40rUJmq6Le2PUbzZ7YkqRN2YnAPsAxVXXFmM8iaf68B7gaeOe4DyJpJH4OfAt4B/DHwCHA94Ezkzx3nAeTJGlCXUSTA+/dO5hkMbAHMFP7zvlav9EMsSVJm6QkbwIOp+n39dZxn0fS/EhyIPBc4BVVdee4zyNpfiV5LPBV4PNV9TdV9fGqej/Nyx5vBE5t/6aVJEmaP2cBRfPS9F6H0rT1OmP9QJJdk+w21/WjYjsRSdImJ8lxwN8BH8TemdLESLKIpvr608CNSR7ePtqxvd+vHVtdVbeM4YiSNt4ymt6ZZ/cOVtWaJP9K8wfUOwNXLfzRJEmaTFV1WZJTgMOTrKT57+3dgSOB8/nV9pznAjsBmeP6kTDEliRtUtoA+1jgNOCQqqrxnkjSPLo3sB3wvPaa7sD2+huaNgSSNj3r/1CqX7X1vabdJUnS/DkKWAUcRvPf2quBk2nac65bgPUbJf7eX5MoybeAbapq53GfRdL8SXIMzcveTgcOWoh/UUpaOEm2BF7Q59F2wLuBzwDvBy6tqisX8myS5keSE2h+E/zaqnpbz/i2wHdoqrS3q6q7xnJASZLUSYbYmhhJXkTz1x0AjgC2Apa3X19bVaeP5WCS5kWSVwLvAq4DjgamB9g3VdXnF/xgkkYuyc7ANcApVXX4mI8jaSMk2Qn4D+DXaPpnfgW4P01PzZ2BV1bVu8d2QEmS1EmG2JoYSc4Dnj7D4/Or6hkLdxpJ8y3Jh4CXzDLFn3NpQhliS5Mlya7AMcCzgQcAtwGXACdW1coxHk2SJHWUIbYkSZIkSZIkqbOmxn0ASZIkSZIkSZJmYogtSZIkSZIkSeosQ2xJkiRJkiRJUmcZYkuSJEmSJEmSOssQW5IkSZIkSZLUWYbYkiRJkiRJkqTOMsSWJEmSJEmSJHWWIbYkSZJGIsmqJOdtxPrzkqyavxNJkiRJ2hQZYkuSJEmSJEmSOssQW5IkSZIkSZLUWYbYkiRJkiRJkqTOMsSWJEnSRknykCQfTfLTJLcmOSfJrrPMf06SzyW5JcnaJJcmefmAn7V3kg8luTLJmiQ/S/KVJH80bd4/Jqkkj+izx4OS/DLJB4b/biVJkiQtNENsSZIkzVmSbYF/B/4YOB34W2AN8CVg6z7zDwM+B2wD/D3wV8BVwD8lefsAH/lHwG7AR4FXtXvcH1iZ5ICeeae294P77PESYAvgfQN8niRJkqQxS1WN+wySJEnaRCV5C/A64OCq+mDP+Ik0IfP5VfWMduxBwDXAyqo6YNo+/wgcDjyiqq5ux84Ddq6qnXvmbV1Vv5i2dgnwTeCuqnpUz/hXgZ2Bh1TVXT3jVwK/7J0rSZIkqbusxJYkSdLGeCFwE/DhaeP/X5+5fwIsAt6fZGnvBZxD89+mz5ntw3oD7CRLkvw6sAT4IrB7kvv2TF8BPAj4/Z41TwMeAbx/sG9PkiRJ0rjda9wHkCRJ0ibtYcBFvZXOAFX1wyS3TJu7e3v/wiz7PWC2D0uyPfBm4AXA9n2mbAvc2v76LOBE4KU0ITntr+/gnqG7JEmSpI4yxJYkSdJCSXt/MfDDGeZcPePiJDT9tHcH/hG4GPgpcBfwF8AB9PxNw6q6Lck/Ay9L8gDgNppq8E9V1c0b961IkiRJWiiG2JIkSdoYVwOPSLLFtL7TD6Kpiu71vfa+uqpmq8aeyeOA3wSOr6pjex8kOWSGNSuAV9K8zPGnNK1HbCUiSZIkbULsiS1JkqSN8UmaFiAvnjb+2j5zPwrcDrwxyb2nP0xyvySLZvms9SF5egeTPAb4o34LqupS4ELgYJpWItfRVHNLkiRJ2kRYiS1JkqSN8TaaNh6nJnki8G3gGcA+wOreiVX1X0leAbwP+G6S04Frge2Ax9K8JPJRwKoZPuu77f6vSbIEuAJ4JPAy4DLgiTOsW9F+JsAbq2rdsN+kJEmSpPExxJYkSdKcVdVPkjwVeCd3V2OfDzwTOLfP/A8muRL4a5rweVuasPsK4Gjgxlk+664kzwPeQdMeZGvgW+2vf5OZQ+z/055vG+CDw32HkiRJksYtVTXuM0iSJEkj07Yo+SFwUVX9zrjPI0mSJGk49sSWJEnSpPtz4Ndo2opIkiRJ2sRYiS1JkqSJlOT5wE7AccBNwOOq6q5ZF0mSJEnqHENsSZIkTaQkq4AdgG8Ah1TVt8d7IkmSJElzYYgtSZIkSZIkSeose2JLkiRJkiRJkjrLEFuSJEmSJEmS1FmG2JIkSZIkSZKkzjLEliRJkiRJkiR1liG2JEmSJEmSJKmzDLElSZIkSZIkSZ31/wCJJP4MBYEMZQAAAABJRU5ErkJggg==\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ - "# IMPORTANT: The 2-D plots here are for the 1st experiment in the experiments dict above\n", - "# 2-D heatmap plots across runs: Training runs: with std dev across the runs\n", + "# 2-D heatmap plots across 10 runs: Training runs: with std dev across the runs\n", "# There seems to be a bug with matplotlib - x and y axes tick labels are not correctly set even though we pass them. Please feel free to look into the code and suggest a correction if you find it.\n", "mdpp_analysis.plot_2d_heatmap(list_exp_data, save_fig)" ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": { "scrolled": false }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/mnt/484A4CAB4A4C9798/GoogleDrive/Maestria-Drive/HiWi/mdp-playground/mdp_playground/analysis/analysis.py:546: UserWarning: FixedFormatter should only be used together with FixedLocator\n", - " plt.gca().set_xticklabels(tick_labels[0])\n" - ] - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/mnt/484A4CAB4A4C9798/GoogleDrive/Maestria-Drive/HiWi/mdp-playground/mdp_playground/analysis/analysis.py:566: UserWarning: FixedFormatter should only be used together with FixedLocator\n", - " plt.gca().set_xticklabels(tick_labels[0])\n" - ] - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ - "# 2-D heatmap plots across runs: Evaluation runs: with std dev across the runs\n", - "mdpp_analysis.plot_2d_heatmap(list_exp_data, save_fig, train=False)" + "# 2-D heatmap plots across 10 runs: Evaluation runs: with std dev across the runs\n", + "if load_eval:\n", + " mdpp_analysis.plot_2d_heatmap(list_exp_data, save_fig, train=False)" ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAACbUAAAFACAYAAACBNgMyAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAAEAAElEQVR4nOzdd5xcdb3/8ddnyu6mdwKEEppSpCiIWFCxi17Fn9dy7RV7R6/lekWuWFFRURBUepemIEhvoQcICemkl02y2WwvM3PO9/fHOTNzZubM9pLdvJ955LFnTv1O/Z7yOZ+POecQERERERERERERERERERERERER2R0kRrsBIiIiIiIiIiIiIiIiIiIiIiIiInkKahMREREREREREREREREREREREZHdhoLaREREREREREREREREREREREREZLehoDYRERERERERERERERERERERERHZbSioTURERERERERERERERERERERERHYbCmoTERERERERERERERERERERERGR3YaC2kRGgZl9wsxc+P8Tw7ytMyPbev1wbktERGRPob5cRERk7FI/LiIiMrapLxcRERnb1JeLSF8pqE1Exjwzm2Rm3zSzBWa23cy6zGy9mV1rZm8d7faJiIhIPDObaGavNLOvmNklZrbEzHI6ySAiIrL7M7MDzOxzZnZl2Ie3mFnGzHaY2cNmdpaZHTDa7RQREZH+MbMZZlYfOTZ3ZjZ/tNslIiIilSzwDjO7ysxWmVmbmWXNrMHMHjGzn5rZIaPdTpGBSo12A0REBsPMXgr8HTi4bNIB4f/3m9mVwKecc5mRbp+IiIj0aCMwc7QbISIiIv1jZjcD7wIsZvLs8P+rge+Y2f84584ZweaJiIjI4PwGmDvajRAREZGemdls4Hrg9TGTZwGvDP9/y8x+6Jz75Qg2T2RIKKhNRMYsMzsQuJ3iAfYTwBVAA3A0cDpBh/1hwAEfHYVmioiISHXJsscbgBpg71Foi4iIiPTdSygGtD0J3AesBFqA/YD3EgS11QK/MrNa59zZo9FQERER6TszezPwCcAHMkDdqDZIREREYplZiuA6+QnhqC7gMmARsAvYH/gP4DUE59x/YWZtzrk/jUJzRQZMQW0iMpadSzGg7W/AZ51zfvj4ajP7M/AgQca2j5jZNc6520a+mSIiIlLFLcAKYCGw0DnXYGaXAB8f1VaJ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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "# Plot learning curves: Training: Each curve corresponds to a different seed for the agent\n", "mdpp_analysis.plot_learning_curves(list_exp_data, save_fig)" @@ -373,25 +173,13 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "# Plot learning curves: Evaluation: Each curve corresponds to a different seed for the agent\n", - "mdpp_analysis.plot_learning_curves(list_exp_data, save_fig, train=False)" + "if load_eval:\n", + " mdpp_analysis.plot_learning_curves(list_exp_data, save_fig, train=False)" ] }, { @@ -403,11 +191,12 @@ "outputs": [], "source": [ "weights = {}\n", + "# for continuous_experiments\n", "weights['reward_noise'] = [.2, .2, .2, .2, .2, .0, .0, .0]\n", "weights['action_loss_weight'] = [.33, .33, .33, .0, .0, .0]\n", "\n", "# Plot radar(spider) plot: Training: across different meta-features\n", - "mdpp_analysis.plot_radar(list_exp_data, save_fig, weights=weights)" + "mdpp_analysis.plot_radar(list_exp_data, save_fig=save_fig, weights=weights)\n" ] }, { @@ -417,25 +206,15 @@ "outputs": [], "source": [ "# Plot radar(spider) plot: Evaluation: across different meta-features\n", - "mdpp_analysis.plot_radar(list_exp_data, save_fig, train=False)" + "if load_eval:\n", + " mdpp_analysis.plot_radar(list_exp_data, save_fig=save_fig, train=False)" ] }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "dir_name /home/rajanr/mdpp_12744267_SAC_target_radius_can_use_as_sample\n", - "Writing BOHB to cave output to /home/rajanr/mdpp_to_cave\n", - "\u001b[1;31mLoading data from a sequential run/already combined runs of experiment configurations.\u001b[0;0m\n", - "/home/rajanr/mdpp_to_cave/sac_move_to_a_point_target_radius\n" - ] - } - ], + "outputs": [], "source": [ "# Setup to analyse an MDP Playground experiment\n", "from mdp_playground.analysis import MDPP_Analysis\n", @@ -496,13 +275,6 @@ "# cave.compare_default_incumbent()\n", "# cave.overview_table()" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { From 9f016d2f2c0cc137f755cdde5499f4a7e821d679 Mon Sep 17 00:00:00 2001 From: Raghu Rajan Date: Tue, 5 Oct 2021 17:23:49 +0200 Subject: [PATCH 14/22] Update to_bohb_results() --- mdp_playground/analysis/mdpp_to_cave.py | 41 +++++++++++++++++++++---- plot_experiments.ipynb | 2 +- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/mdp_playground/analysis/mdpp_to_cave.py b/mdp_playground/analysis/mdpp_to_cave.py index 99218ba..af30b48 100644 --- a/mdp_playground/analysis/mdpp_to_cave.py +++ b/mdp_playground/analysis/mdpp_to_cave.py @@ -2,6 +2,7 @@ import pandas as pd import argparse, os import json +from mdp_playground.analysis import MDPP_Analysis class MDPPToCave(): def __init__(self): @@ -143,6 +144,8 @@ def to_bohb_results(self, input_dir, exp_name, output_dir="../cave_output/", configs.json, results.json, configspace.json, in output_dir/exp_name. This file can be fed into cave for further analysis. + Currently only compatible with the MDPP expt. of type: grid of configs + exp_name : str Should be the expt name from MDPP, i.e., the "prefix" of the CSV stats files. A sub-directory of output_dir is created with this name to store BOHB format stats files. @@ -159,8 +162,18 @@ def to_bohb_results(self, input_dir, exp_name, output_dir="../cave_output/", os.makedirs(output_dir_final) + # Read current CSVs + + ##TODO Re-use code from analyis.py to load data instead of processing it again here: + # mdpp_analysis = MDPP_Analysis() + # self.exp_data = mdpp_analysis.get_exp_data(dir_name=input_dir, + # exp_name=exp_name, + # ) + # print("exp_data:\n", self.exp_data) + + # exp_data["dims_varied"] + # exp_data["dims_values"] - # Read current csvs ## stats_file = os.path.join(input_dir, exp_name) stats_file = os.path.abspath(stats_file) self._read_stats(stats_file) @@ -176,7 +189,7 @@ def to_bohb_results(self, input_dir, exp_name, output_dir="../cave_output/", sep=' ') remove_names = ["training_iteration", "algorithm", "seed"] - parameters = col_names[:-3].copy()#All paramaters tracked in run + parameters = col_names[:-3].copy() # All parameters tracked in run for x in col_names: for name in remove_names: if(name in x): @@ -201,15 +214,25 @@ def to_bohb_results(self, input_dir, exp_name, output_dir="../cave_output/", ##------------- Start converting csv ----------------## #configspace and scenario file configspace = self._create_configspace_json(stats_pd, var_configs) - output_configspace = os.path.join(output_dir_final,'configspace.json') - with open(output_configspace, 'w') as fp: + cs_json_file = os.path.join(output_dir_final, 'configspace.json') + if os.path.exists(cs_json_file): + if not overwrite: + raise FileExistsError() + + with open(cs_json_file, 'w') as fp: json.dump(configspace, fp, indent=2) + # print("var_configs:", var_configs) + #Trajectory and runhistory files #Finding end configuration training diff_configs = stats_pd.iloc[final_rows_for_a_config] + # print("diff_configs:", diff_configs) diff_configs = diff_configs.groupby(var_configs) + # print("grouped by", diff_configs) configs_mean = diff_configs.mean() + # print("mean:", configs_mean) + # print("diff_configs.groups:", diff_configs.groups) diff_configs_results = [] #results.json diff_configs_lst = [] budget = stats_pd["timesteps_total"].iloc[final_rows_for_a_config[0]]#all have the same budget @@ -244,14 +267,20 @@ def to_bohb_results(self, input_dir, exp_name, output_dir="../cave_output/", #configs.json output_configs = os.path.join(output_dir_final,'configs.json') + if os.path.exists(output_configs): + if not overwrite: + raise FileExistsError() with open(output_configs, 'w') as fout: for d in diff_configs_lst: json.dump(d, fout) fout.write('\n') #results.json - output_configs = os.path.join(output_dir_final,'results.json') - with open(output_configs, 'w') as fout: + output_results = os.path.join(output_dir_final,'results.json') + if os.path.exists(output_results): + if not overwrite: + raise FileExistsError() + with open(output_results, 'w') as fout: for d in diff_configs_results: json.dump(d, fout) fout.write('\n') diff --git a/plot_experiments.ipynb b/plot_experiments.ipynb index f6ae74e..d8d58ff 100644 --- a/plot_experiments.ipynb +++ b/plot_experiments.ipynb @@ -244,7 +244,7 @@ "for exp_name, loc in experiments.items():\n", " dir_name, _ = os.path.split(loc)\n", " print(\"dir_name\", _, dir_name)\n", - " cave_input_file = mdpp_cave.to_bohb_results(dir_name, exp_name, output_dir)\n", + " cave_input_file = mdpp_cave.to_bohb_results(dir_name, exp_name, output_dir, overwrite=True)\n", " print(cave_input_file)\n", " # Similarly, as an example, cave will ouput it's results \n", " # to the same directory as cave's input files\n", From 5229d634ae818ac556110192f06fd39a60217393 Mon Sep 17 00:00:00 2001 From: Raghu Rajan Date: Wed, 6 Oct 2021 00:06:49 +0200 Subject: [PATCH 15/22] Made reading in stats more robust, improved MDPP to cave conversion --- mdp_playground/analysis/analysis.py | 2 +- mdp_playground/analysis/mdpp_to_cave.py | 32 ++++++++++++++++++++++--- plot_experiments.ipynb | 27 +++++++-------------- 3 files changed, 38 insertions(+), 23 deletions(-) diff --git a/mdp_playground/analysis/analysis.py b/mdp_playground/analysis/analysis.py index 418a5ce..902bfaf 100644 --- a/mdp_playground/analysis/analysis.py +++ b/mdp_playground/analysis/analysis.py @@ -236,7 +236,7 @@ def join_files(file_prefix, file_suffix): for i in range(stats_pd.shape[0] - 1): if ( stats_pd["timesteps_total"].iloc[i] - > stats_pd["timesteps_total"].iloc[i + 1] + >= stats_pd["timesteps_total"].iloc[i + 1] ): final_rows_for_a_config.append(i) diff --git a/mdp_playground/analysis/mdpp_to_cave.py b/mdp_playground/analysis/mdpp_to_cave.py index af30b48..99a6296 100644 --- a/mdp_playground/analysis/mdpp_to_cave.py +++ b/mdp_playground/analysis/mdpp_to_cave.py @@ -3,6 +3,7 @@ import argparse, os import json from mdp_playground.analysis import MDPP_Analysis +from cave.cavefacade import CAVE class MDPPToCave(): def __init__(self): @@ -149,6 +150,9 @@ def to_bohb_results(self, input_dir, exp_name, output_dir="../cave_output/", exp_name : str Should be the expt name from MDPP, i.e., the "prefix" of the CSV stats files. A sub-directory of output_dir is created with this name to store BOHB format stats files. + overwrite : bool + If existing files should be overwritten. + Returns "/" ''' @@ -224,8 +228,8 @@ def to_bohb_results(self, input_dir, exp_name, output_dir="../cave_output/", # print("var_configs:", var_configs) - #Trajectory and runhistory files - #Finding end configuration training + # Trajectory and runhistory files + # Finding end configuration training diff_configs = stats_pd.iloc[final_rows_for_a_config] # print("diff_configs:", diff_configs) diff_configs = diff_configs.groupby(var_configs) @@ -235,7 +239,7 @@ def to_bohb_results(self, input_dir, exp_name, output_dir="../cave_output/", # print("diff_configs.groups:", diff_configs.groups) diff_configs_results = [] #results.json diff_configs_lst = [] - budget = stats_pd["timesteps_total"].iloc[final_rows_for_a_config[0]]#all have the same budget + budget = stats_pd["timesteps_total"].iloc[final_rows_for_a_config[0]] # all have the same budget aux = 0 for i, group_name in enumerate(diff_configs.groups): group_labels = diff_configs.groups[group_name] @@ -284,9 +288,31 @@ def to_bohb_results(self, input_dir, exp_name, output_dir="../cave_output/", for d in diff_configs_results: json.dump(d, fout) fout.write('\n') + return output_dir_final + def to_CAVE_object(self, input_dir, exp_name, output_dir="../cave_output/", + overwrite=False): + '''Converts MDP Playground stats CSVs to BOHB format stats files and creates + a CAVE object from them. + + Please see to_bohb_results() for details about some of the parameters. + ''' + + cave_input_file = self.to_bohb_results(input_dir, exp_name, output_dir, overwrite=overwrite) + + cave_results = os.path.join(cave_input_file, "out") + cave = CAVE(folders = [cave_input_file], + output_dir = cave_results, + ta_exec_dir = [cave_input_file], + file_format = "BOHB", + show_jupyter=True, + ) + + return cave + + if __name__ == "__main__": input_dir = '../mdp_files/' exp_name = 'dqn_seq_del' diff --git a/plot_experiments.ipynb b/plot_experiments.ipynb index d8d58ff..6e7aeb0 100644 --- a/plot_experiments.ipynb +++ b/plot_experiments.ipynb @@ -241,29 +241,18 @@ "#The converted mdpp csvs will be stored in output_dir\n", "output_dir = \"/home/rajanr/mdpp_to_cave\"\n", "mdpp_cave = MDPPToCave()\n", - "for exp_name, loc in experiments.items():\n", - " dir_name, _ = os.path.split(loc)\n", - " print(\"dir_name\", _, dir_name)\n", - " cave_input_file = mdpp_cave.to_bohb_results(dir_name, exp_name, output_dir, overwrite=True)\n", - " print(cave_input_file)\n", - " # Similarly, as an example, cave will ouput it's results \n", - " # to the same directory as cave's input files\n", + "for exp_name, dir_name in experiments.items():\n", "\n", - "# cave_results = os.path.join(cave_input_file, \"out\")\n", - "# cave = CAVE(folders = [cave_input_file],\n", - "# output_dir = cave_results,\n", - "# ta_exec_dir = [cave_input_file],\n", - "# file_format = \"BOHB\",\n", - "# show_jupyter=True,\n", - "# )\n", - "# cave.performance_table()\n", - "# cave.local_parameter_importance()\n", + " cave = mdpp_cave.to_CAVE_object(dir_name, exp_name, output_dir, overwrite=True)\n", + "\n", + " cave.performance_table()\n", + "# cave.local_parameter_importance() # Bug: https://github.com/automl/CAVE/pull/296/files\n", " # cave.cave_fanova() # Only for experiments varying more than 1 meta-feature\n", "\n", "# Other analysis\n", - "# cave.parallel_coordinates()\n", - "# cave.cost_over_time()\n", - "# cave.algorithm_footprints()\n", + "# cave.parallel_coordinates() # crashes\n", + "# cave.cost_over_time()\n", + "# cave.algorithm_footprints()\n", "# cave.pimp_comparison_table()\n", "# cave.cave_ablation()\n", "# cave.pimp_forward_selection()\n", From dfe7f86da4d759ce77ed128257a9679662be9dae Mon Sep 17 00:00:00 2001 From: Raghu Rajan Date: Wed, 6 Oct 2021 15:41:29 +0200 Subject: [PATCH 16/22] Deleted some experiments --- experiments/a3c_del.py | 113 ------------------------------------ experiments/a3c_lstm_del.py | 108 ---------------------------------- experiments/a3c_lstm_seq.py | 107 ---------------------------------- experiments/a3c_seq.py | 105 --------------------------------- 4 files changed, 433 deletions(-) delete mode 100644 experiments/a3c_del.py delete mode 100644 experiments/a3c_lstm_del.py delete mode 100644 experiments/a3c_lstm_seq.py delete mode 100644 experiments/a3c_seq.py diff --git a/experiments/a3c_del.py b/experiments/a3c_del.py deleted file mode 100644 index bb626a3..0000000 --- a/experiments/a3c_del.py +++ /dev/null @@ -1,113 +0,0 @@ -from mdp_playground.config_processor.config_processor import get_grid_of_configs, combined_processing - - -num_seeds = 10 -timesteps_total = 1000000 -from collections import OrderedDict -var_env_configs = OrderedDict({ - 'state_space_size': [8],#, 10, 12, 14] # [2**i for i in range(1,6)] - 'action_space_size': [8],#2, 4, 8, 16] # [2**i for i in range(1,6)] - 'delay': [0] + [2**i for i in range(4)], - 'sequence_length': [1], - 'reward_density': [0.25], # np.linspace(0.0, 1.0, num=5) - 'make_denser': [False], - 'terminal_state_density': [0], # np.linspace(0.1, 1.0, num=5) - 'transition_noise': [0],#, 0.01, 0.02, 0.10, 0.25] - 'reward_noise': [0],#, 1, 5, 10, 25] # Std dev. of normal dist. - 'dummy_seed': [i for i in range(num_seeds)], -}) - -var_agent_configs = OrderedDict({ - # Learning rate - "lr": [1e-3], - # Value Function Loss coefficient - "vf_loss_coeff": [0.1, 0.5, 2.5], - # Entropy coefficient - "entropy_coeff": [0.001, 0.01, 0.1, 1], -}) - -var_configs = OrderedDict({ -"env": var_env_configs, -"agent": var_agent_configs -}) - -env_config = { - "env": "RLToy-v0", - "horizon": 100, - "env_config": { - "seed": 0, # seed - "state_space_type": "discrete", - "action_space_type": "discrete", - "generate_random_mdp": True, - "repeats_in_sequences": False, - "reward_scale": 1.0, - "completely_connected": True, - }, -} - -timesteps_total = 1e6 -algorithm = "A3C" -agent_config = { - # Size of rollout batch - "sample_batch_size": 10, # maybe num_workers * sample_batch_size * num_envs_per_worker * grads_per_step - "train_batch_size": 100, # seems to have no effect - # Use PyTorch as backend - no LSTM support - "use_pytorch": False, - # GAE(gamma) parameter - "gamma": 0.99, - "lambda": 0.95, # - # Max global norm for each gradient calculated by worker - "grad_clip": 10.0, # low prio. - # Learning rate schedule - "lr_schedule": "linear", - # Min time per iteration - "min_iter_time_s": 0, - # Workers sample async. Note that this increases the effective - # sample_batch_size by up to 5x due to async buffering of batches. - "sample_async": True, - "timesteps_per_iteration": 1000, - "num_workers": 3, - "num_envs_per_worker": 5, - - "optimizer": { - "grads_per_step": 10 - }, -} - -filters_100x100 = [ - [16, [8, 8], 4], - [32, [4, 4], 2], - [256, [13, 13], 1], -] - -model_config = { - "model": { - "fcnet_hiddens": [128, 128, 128], - "conv_filters": filters_100x100, - "custom_preprocessor": "ohe", - "custom_options": {}, # extra options to pass to your preprocessor - "fcnet_activation": "tanh", - "use_lstm": False, - }, -} - - -eval_config = { - "evaluation_interval": 1, # I think this means every x training_iterations - "evaluation_config": { - "explore": False, - "exploration_fraction": 0, - "exploration_final_eps": 0, - "evaluation_num_episodes": 10, - "horizon": 100, - "env_config": { - "dummy_eval": True, # hack Used to check if we are in evaluation mode or training mode inside Ray callback on_episode_end() to be able to write eval stats - "transition_noise": 0 - if "state_space_type" in env_config["env_config"] - and env_config["env_config"]["state_space_type"] == "discrete" - else tune.function(lambda a: a.normal(0, 0)), - "reward_noise": tune.function(lambda a: a.normal(0, 0)), - "action_loss_weight": 0.0, - }, - }, -} diff --git a/experiments/a3c_lstm_del.py b/experiments/a3c_lstm_del.py deleted file mode 100644 index c63c532..0000000 --- a/experiments/a3c_lstm_del.py +++ /dev/null @@ -1,108 +0,0 @@ -num_seeds = 10 -timesteps_total = 1000000 -from collections import OrderedDict -var_env_configs = OrderedDict({ - 'state_space_size': [8],#, 10, 12, 14] # [2**i for i in range(1,6)] - 'action_space_size': [8],#2, 4, 8, 16] # [2**i for i in range(1,6)] - 'delay': [0] + [2**i for i in range(4)], - 'sequence_length': [1], - 'reward_density': [0.25], # np.linspace(0.0, 1.0, num=5) - 'make_denser': [False], - 'terminal_state_density': [0.25], # np.linspace(0.1, 1.0, num=5) - 'transition_noise': [0],#, 0.01, 0.02, 0.10, 0.25] - 'reward_noise': [0],#, 1, 5, 10, 25] # Std dev. of normal dist. - 'dummy_seed': [i for i in range(num_seeds)], -}) - -var_configs = OrderedDict({ -"env": var_env_configs -}) - -env_config = { - "env": "RLToy-v0", - "horizon": 100, - "env_config": { - 'seed': 0, #seed - 'state_space_type': 'discrete', - 'action_space_type': 'discrete', - 'generate_random_mdp': True, - 'repeats_in_sequences': False, - 'reward_scale': 1.0, - 'completely_connected': True, - }, -} - -timesteps_total = 1e6 -algorithm = "A3C" -agent_config = { - # Size of rollout batch - "sample_batch_size": 10, # maybe num_workers * sample_batch_size * num_envs_per_worker * grads_per_step - "train_batch_size": 100, # seems to have no effect - # Use PyTorch as backend - no LSTM support - "use_pytorch": False, - # GAE(gamma) parameter - "gamma": 0.99, - "lambda": 0.95, # - # Max global norm for each gradient calculated by worker - "grad_clip": 10.0, # low prio. - # Learning rate - "lr": 0.0001, # - # Learning rate schedule - "lr_schedule": None, - # Value Function Loss coefficient - "vf_loss_coeff": 0.1, # - # Entropy coefficient - "entropy_coeff": 0.1, # - # Min time per iteration - "min_iter_time_s": 0, - # Workers sample async. Note that this increases the effective - # sample_batch_size by up to 5x due to async buffering of batches. - "sample_async": True, - "timesteps_per_iteration": 1000, - "num_workers": 3, - "num_envs_per_worker": 5, - - "optimizer": { - "grads_per_step": 1 - }, -} - -model_config = { - "model": { - "fcnet_hiddens": [128, 128, 128], - "custom_preprocessor": "ohe", - "custom_options": {}, # extra options to pass to your preprocessor - "fcnet_activation": "tanh", - "use_lstm": True, - "lstm_cell_size": 64, - "lstm_use_prev_action_reward": True, - }, -} - -from ray import tune -eval_config = { - "evaluation_interval": 1, # I think this means every x training_iterations - "evaluation_config": { - "explore": False, - "exploration_fraction": 0, - "exploration_final_eps": 0, - "evaluation_num_episodes": 10, - "horizon": 100, - "env_config": { - "dummy_eval": True, #hack Used to check if we are in evaluation mode or training mode inside Ray callback on_episode_end() to be able to write eval stats - 'transition_noise': 0 if "state_space_type" in env_config["env_config"] and env_config["env_config"]["state_space_type"] == "discrete" else tune.function(lambda a: a.normal(0, 0)), - 'reward_noise': tune.function(lambda a: a.normal(0, 0)), - 'action_loss_weight': 0.0, - } - }, -} - -value_tuples = [] -for config_type, config_dict in var_configs.items(): - for key in config_dict: - assert type(var_configs[config_type][key]) == list, "var_config should be a dict of dicts with lists as the leaf values to allow each configuration option to take multiple possible values" - value_tuples.append(var_configs[config_type][key]) - -import itertools -cartesian_product_configs = list(itertools.product(*value_tuples)) -print("Total number of configs. to run:", len(cartesian_product_configs)) diff --git a/experiments/a3c_lstm_seq.py b/experiments/a3c_lstm_seq.py deleted file mode 100644 index 6e90b08..0000000 --- a/experiments/a3c_lstm_seq.py +++ /dev/null @@ -1,107 +0,0 @@ -num_seeds = 10 -timesteps_total = 1000000 -from collections import OrderedDict -var_env_configs = OrderedDict({ - 'state_space_size': [8],#, 10, 12, 14] # [2**i for i in range(1,6)] - 'action_space_size': [8],#2, 4, 8, 16] # [2**i for i in range(1,6)] - 'delay': [0], - 'sequence_length': [1, 2, 3, 4],#i for i in range(1,4)] - 'reward_density': [0.25], # np.linspace(0.0, 1.0, num=5) - 'make_denser': [False], - 'terminal_state_density': [0.25], # np.linspace(0.1, 1.0, num=5) - 'transition_noise': [0],#, 0.01, 0.02, 0.10, 0.25] - 'reward_noise': [0],#, 1, 5, 10, 25] # Std dev. of normal dist. - 'dummy_seed': [i for i in range(num_seeds)], -}) - -var_configs = OrderedDict({ -"env": var_env_configs -}) - -env_config = { - "env": "RLToy-v0", - "horizon": 100, - "env_config": { - 'seed': 0, #seed - 'state_space_type': 'discrete', - 'action_space_type': 'discrete', - 'generate_random_mdp': True, - 'repeats_in_sequences': False, - 'reward_scale': 1.0, - 'completely_connected': True, - }, -} - -algorithm = "A3C" -agent_config = { - # Size of rollout batch - "sample_batch_size": 10, # maybe num_workers * sample_batch_size * num_envs_per_worker * grads_per_step - "train_batch_size": 100, # seems to have no effect - # Use PyTorch as backend - no LSTM support - "use_pytorch": False, - # GAE(gamma) parameter - "gamma": 0.99, - "lambda": 0, # - # Max global norm for each gradient calculated by worker - "grad_clip": 10.0, # low prio. - # Learning rate - "lr": 0.0001, # - # Learning rate schedule - "lr_schedule": None, - # Value Function Loss coefficient - "vf_loss_coeff": 0.1, # - # Entropy coefficient - "entropy_coeff": 0.1, # - # Min time per iteration - "min_iter_time_s": 0, - # Workers sample async. Note that this increases the effective - # sample_batch_size by up to 5x due to async buffering of batches. - "sample_async": True, - "timesteps_per_iteration": 1000, - "num_workers": 3, - "num_envs_per_worker": 5, - - "optimizer": { - "grads_per_step": 10 - }, -} - -model_config = { - "model": { - "fcnet_hiddens": [128, 128, 128], - "custom_preprocessor": "ohe", - "custom_options": {}, # extra options to pass to your preprocessor - "fcnet_activation": "tanh", - "use_lstm": True, - "lstm_cell_size": 64, - "lstm_use_prev_action_reward": True, - }, -} - -from ray import tune -eval_config = { - "evaluation_interval": 1, # I think this means every x training_iterations - "evaluation_config": { - "explore": False, - "exploration_fraction": 0, - "exploration_final_eps": 0, - "evaluation_num_episodes": 10, - "horizon": 100, - "env_config": { - "dummy_eval": True, #hack Used to check if we are in evaluation mode or training mode inside Ray callback on_episode_end() to be able to write eval stats - 'transition_noise': 0 if "state_space_type" in env_config["env_config"] and env_config["env_config"]["state_space_type"] == "discrete" else tune.function(lambda a: a.normal(0, 0)), - 'reward_noise': tune.function(lambda a: a.normal(0, 0)), - 'action_loss_weight': 0.0, - } - }, -} - -value_tuples = [] -for config_type, config_dict in var_configs.items(): - for key in config_dict: - assert type(var_configs[config_type][key]) == list, "var_config should be a dict of dicts with lists as the leaf values to allow each configuration option to take multiple possible values" - value_tuples.append(var_configs[config_type][key]) - -import itertools -cartesian_product_configs = list(itertools.product(*value_tuples)) -print("Total number of configs. to run:", len(cartesian_product_configs)) diff --git a/experiments/a3c_seq.py b/experiments/a3c_seq.py deleted file mode 100644 index 1ab720f..0000000 --- a/experiments/a3c_seq.py +++ /dev/null @@ -1,105 +0,0 @@ -num_seeds = 10 -timesteps_total = 1000000 -from collections import OrderedDict -var_env_configs = OrderedDict({ - 'state_space_size': [8],#, 10, 12, 14] # [2**i for i in range(1,6)] - 'action_space_size': [8],#2, 4, 8, 16] # [2**i for i in range(1,6)] - 'delay': [0], - 'sequence_length': [1, 2, 3, 4],#i for i in range(1,4)] - 'reward_density': [0.25], # np.linspace(0.0, 1.0, num=5) - 'make_denser': [False], - 'terminal_state_density': [0.25], # np.linspace(0.1, 1.0, num=5) - 'transition_noise': [0],#, 0.01, 0.02, 0.10, 0.25] - 'reward_noise': [0],#, 1, 5, 10, 25] # Std dev. of normal dist. - 'dummy_seed': [i for i in range(num_seeds)], -}) - -var_configs = OrderedDict({ -"env": var_env_configs -}) - -env_config = { - "env": "RLToy-v0", - "horizon": 100, - "env_config": { - 'seed': 0, #seed - 'state_space_type': 'discrete', - 'action_space_type': 'discrete', - 'generate_random_mdp': True, - 'repeats_in_sequences': False, - 'reward_scale': 1.0, - 'completely_connected': True, - }, -} - -algorithm = "A3C" -agent_config = { - # Size of rollout batch - "sample_batch_size": 10, # maybe num_workers * sample_batch_size * num_envs_per_worker * grads_per_step - "train_batch_size": 100, # seems to have no effect - # Use PyTorch as backend - no LSTM support - "use_pytorch": False, - # GAE(gamma) parameter - "gamma": 0.99, - "lambda": 0.95, # - # Max global norm for each gradient calculated by worker - "grad_clip": 10.0, # low prio. - # Learning rate - "lr": 0.0001, # - # Learning rate schedule - "lr_schedule": None, - # Value Function Loss coefficient - "vf_loss_coeff": 0.1, # - # Entropy coefficient - "entropy_coeff": 0.1, # - # Min time per iteration - "min_iter_time_s": 0, - # Workers sample async. Note that this increases the effective - # sample_batch_size by up to 5x due to async buffering of batches. - "sample_async": True, - "timesteps_per_iteration": 1000, - "num_workers": 3, - "num_envs_per_worker": 5, - - "optimizer": { - "grads_per_step": 10 - }, -} - -model_config = { - "model": { - "fcnet_hiddens": [128, 128, 128], - "custom_preprocessor": "ohe", - "custom_options": {}, # extra options to pass to your preprocessor - "fcnet_activation": "tanh", - "use_lstm": False, - }, -} - -from ray import tune -eval_config = { - "evaluation_interval": 1, # I think this means every x training_iterations - "evaluation_config": { - "explore": False, - "exploration_fraction": 0, - "exploration_final_eps": 0, - "evaluation_num_episodes": 10, - "horizon": 100, - "env_config": { - "dummy_eval": True, #hack Used to check if we are in evaluation mode or training mode inside Ray callback on_episode_end() to be able to write eval stats - 'transition_noise': 0 if "state_space_type" in env_config["env_config"] and env_config["env_config"]["state_space_type"] == "discrete" else tune.function(lambda a: a.normal(0, 0)), - 'reward_noise': tune.function(lambda a: a.normal(0, 0)), - 'action_loss_weight': 0.0, - } - }, -} - -value_tuples = [] -for config_type, config_dict in var_configs.items(): - for key in config_dict: - assert type(var_configs[config_type][key]) == list, "var_config should be a dict of dicts with lists as the leaf values to allow each configuration option to take multiple possible values" - value_tuples.append(var_configs[config_type][key]) - -import itertools -cartesian_product_configs = list(itertools.product(*value_tuples)) -print("Total number of configs. to run:", len(cartesian_product_configs)) From 7d2c02a5d42cf627315ac956ce80658f938cc388 Mon Sep 17 00:00:00 2001 From: Raghu Rajan Date: Wed, 6 Oct 2021 17:37:59 +0200 Subject: [PATCH 17/22] add tests --- .gitignore | 3 + .../sac_move_to_a_point_target_radius.csv | 1000 ++ ...sac_move_to_a_point_target_radius_eval.csv | 10450 ++++++++++++++++ tests/test_analysis_code.py | 61 + tests/test_run_experiments.py | 2 +- 5 files changed, 11515 insertions(+), 1 deletion(-) create mode 100644 tests/files/mdpp_12744267_SAC_target_radius/sac_move_to_a_point_target_radius.csv create mode 100644 tests/files/mdpp_12744267_SAC_target_radius/sac_move_to_a_point_target_radius_eval.csv create mode 100644 tests/test_analysis_code.py diff --git a/.gitignore b/.gitignore index 50471ce..8968f0c 100644 --- a/.gitignore +++ b/.gitignore @@ -108,3 +108,6 @@ venv.bak/ *pickle*dat .vscode/ + +#whitelist +!tests/files/mdpp_12744267_SAC_target_radius/*.csv diff --git a/tests/files/mdpp_12744267_SAC_target_radius/sac_move_to_a_point_target_radius.csv b/tests/files/mdpp_12744267_SAC_target_radius/sac_move_to_a_point_target_radius.csv new file mode 100644 index 0000000..a73480d --- /dev/null +++ b/tests/files/mdpp_12744267_SAC_target_radius/sac_move_to_a_point_target_radius.csv @@ -0,0 +1,1000 @@ +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 0 2000 -2.835586428642273 100.0 +2 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 0 3000 -0.7374698380629222 98.23333333333333 +3 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 0 4000 1.4798438185382456 94.35714285714286 +4 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 0 5000 2.4168546180117807 93.90566037735849 +5 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 0 6000 3.1059944752662902 94.87301587301587 +6 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 0 7000 3.680982417351491 94.10810810810811 +7 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 0 8000 4.1313948058301495 94.80952380952381 +8 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 0 9000 4.325466278702654 95.36170212765957 +9 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 0 10000 5.120790490657091 94.85 +10 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 0 11000 6.2393750321865085 94.85 +11 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 0 12000 7.0903212697803975 94.85 +12 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 0 13000 7.18711551785469 96.43 +13 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 0 14000 7.27777010627091 97.4 +14 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 0 15000 7.49090251326561 96.63 +15 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 0 16000 7.4262323769927026 97.17 +16 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 0 17000 7.49219827875495 97.76 +17 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 0 18000 7.4891280220448975 97.76 +18 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 0 19000 7.483744251281023 97.76 +19 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 0 20000 7.462710901796818 98.55 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 1 2000 -4.06567497253418 100.0 +2 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 1 3000 -1.027120475967725 97.86666666666666 +3 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 1 4000 1.0428250208497047 97.0 +4 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 1 5000 2.197940635653037 93.58490566037736 +5 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 1 6000 3.360758234649452 89.11940298507463 +6 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 1 7000 3.718599559715042 90.20779220779221 +7 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 1 8000 4.078196032293912 91.33333333333333 +8 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 1 9000 4.4393455413813445 92.22680412371135 +9 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 1 10000 5.494164308905601 91.65 +10 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 1 11000 6.517143097519875 91.65 +11 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 1 12000 7.041783605515957 91.65 +12 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 1 13000 7.270012003481388 92.88 +13 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 1 14000 7.4044698908179996 92.69 +14 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 1 15000 7.419060056880117 95.92 +15 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 1 16000 7.356649947687983 96.8 +16 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 1 17000 7.426479593589902 96.8 +17 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 1 18000 7.56641975492239 96.8 +18 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 1 19000 7.398130675405264 96.8 +19 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 1 20000 7.405338995903731 96.14 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 2 2000 -5.244668173789978 100.0 +2 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 2 3000 -2.7790171732505162 100.0 +3 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 2 4000 -0.267789120172582 97.2439024390244 +4 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 2 5000 1.1399030755010415 93.13207547169812 +5 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 2 6000 2.060422391704624 94.12698412698413 +6 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 2 7000 2.778453378083363 94.93150684931507 +7 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 2 8000 3.3801391940249736 95.21686746987952 +8 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 2 9000 3.8176252462047464 93.71875 +9 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 2 10000 4.815013976879418 93.97 +10 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 2 11000 6.054009990878403 93.97 +11 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 2 12000 6.947379607148468 93.97 +12 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 2 13000 7.242733683474362 93.38 +13 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 2 14000 7.357305716015398 95.33 +14 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 2 15000 7.514335817322135 96.94 +15 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 2 16000 7.442629296332598 96.97 +16 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 2 17000 7.500849070847035 96.97 +17 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 2 18000 7.5574911020696165 96.36 +18 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 2 19000 7.450141852200031 97.33 +19 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 2 20000 7.431066760867834 97.33 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 3 2000 -3.870935720205307 100.0 +2 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 3 3000 -1.720294050872326 100.0 +3 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 3 4000 0.8088654380823884 95.0 +4 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 3 5000 2.1765823736786842 90.74545454545455 +5 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 3 6000 2.9938352125195355 90.86153846153846 +6 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 3 7000 3.4200098126133285 92.08 +7 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 3 8000 3.910391009737586 92.70930232558139 +8 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 3 9000 4.222260804924493 93.46875 +9 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 3 10000 5.154404475316405 93.72 +10 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 3 11000 6.186303176507354 93.05 +11 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 3 12000 7.109057544842362 92.98 +12 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 3 13000 7.275451270863414 93.83 +13 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 3 14000 7.3941842119395735 96.54 +14 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 3 15000 7.41912313491106 97.51 +15 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 3 16000 7.3962671585381035 98.36 +16 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 3 17000 7.529543034732342 98.36 +17 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 3 18000 7.55028879314661 98.51 +18 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 3 19000 7.417159005999565 98.51 +19 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 3 20000 7.390480869859457 98.52 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 4 2000 -0.2000607892870903 100.0 +2 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 4 3000 2.2248604585727056 100.0 +3 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 4 4000 3.8024919338004532 92.44186046511628 +4 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 4 5000 4.177502333696158 93.20754716981132 +5 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 4 6000 4.595057001307843 93.95238095238095 +6 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 4 7000 4.933414396051675 94.78082191780823 +7 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 4 8000 5.259970888226147 95.40963855421687 +8 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 4 9000 5.286473722467499 95.90322580645162 +9 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 4 10000 5.963455787375569 95.48 +10 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 4 11000 6.648926163986325 95.48 +11 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 4 12000 7.119050098732114 95.48 +12 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 4 13000 7.222778065502643 96.29 +13 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 4 14000 7.276866225078702 98.73 +14 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 4 15000 7.420816977471113 98.03 +15 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 4 16000 7.3579167167842385 98.24 +16 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 4 17000 7.487787589877843 97.69 +17 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 4 18000 7.493642214238644 96.89 +18 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 4 19000 7.459564108997584 96.89 +19 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 4 20000 7.429675435423851 97.6 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 5 2000 -3.409433674812317 100.0 +2 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 5 3000 -0.6447280993064245 99.76666666666667 +3 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 5 4000 1.2212982695549726 98.325 +4 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 5 5000 2.2854308116321382 94.61538461538461 +5 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 5 6000 3.2430008341325447 92.5 +6 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 5 7000 3.7671009779969853 93.22666666666667 +7 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 5 8000 4.192320463411948 94.02352941176471 +8 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 5 9000 4.408791830665187 94.65263157894736 +9 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 5 10000 5.2413407292962075 94.92 +10 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 5 11000 6.425092441588641 94.92 +11 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 5 12000 7.0576106980443 94.44 +12 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 5 13000 7.172181463986635 94.74 +13 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 5 14000 7.265721540153026 95.48 +14 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 5 15000 7.427109104543924 97.17 +15 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 5 16000 7.37234591640532 98.82 +16 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 5 17000 7.518786006197334 97.15 +17 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 5 18000 7.5866292224824425 96.78 +18 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 5 19000 7.459672737568617 96.63 +19 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 5 20000 7.5342672675848 95.93 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 6 2000 -0.647885125875473 100.0 +2 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 6 3000 1.1453283404310544 100.0 +3 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 6 4000 2.695586099312073 97.1951219512195 +4 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 6 5000 3.3274688770373664 96.09803921568627 +5 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 6 6000 3.8726134886507126 96.73770491803279 +6 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 6 7000 4.4323695949087405 94.75342465753425 +7 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 6 8000 4.822525217590562 95.3855421686747 +8 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 6 9000 4.8800878159461485 95.88172043010752 +9 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 6 10000 5.616672233790159 95.84 +10 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 6 11000 6.4752478739619255 95.84 +11 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 6 12000 7.079458776861429 94.97 +12 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 6 13000 7.158473191037774 95.42 +13 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 6 14000 7.268654251769185 96.12 +14 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 6 15000 7.411640345901251 96.96 +15 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 6 16000 7.36250292904675 96.46 +16 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 6 17000 7.434994120821357 98.3 +17 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 6 18000 7.439325690641999 98.3 +18 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 6 19000 7.506799292042851 98.63 +19 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 6 20000 7.423024110719561 98.63 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 7 2000 -5.722899486124516 100.0 +2 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 7 3000 -1.8848948324880292 96.58064516129032 +3 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 7 4000 0.4445025733716431 94.0952380952381 +4 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 7 5000 1.8682947293601253 90.67272727272727 +5 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 7 6000 2.71863378556163 90.5909090909091 +6 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 7 7000 3.2345685538786806 91.82894736842105 +7 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 7 8000 3.7013053943285312 91.36781609195403 +8 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 7 9000 4.127350367871778 91.5 +9 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 7 10000 5.290252297781408 91.67 +10 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 7 11000 6.5080137326940894 91.67 +11 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 7 12000 7.053848411850631 91.67 +12 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 7 13000 7.25082392025739 92.74 +13 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 7 14000 7.4885502041131256 94.27 +14 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 7 15000 7.424036853015423 96.13 +15 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 7 16000 7.353714946359396 95.95 +16 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 7 17000 7.426373118013143 96.53 +17 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 7 18000 7.579367647618056 96.93 +18 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 7 19000 7.427776113897562 95.93 +19 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 7 20000 7.430852471441031 95.93 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 8 2000 -3.5250649437308312 100.0 +2 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 8 3000 -1.2995242153604825 99.16666666666667 +3 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 8 4000 1.000318313698943 96.73170731707317 +4 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 8 5000 2.1495852946953953 93.52830188679245 +5 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 8 6000 2.995205816696398 93.6875 +6 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 8 7000 3.472677689851136 94.54054054054055 +7 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 8 8000 3.952170990141375 95.19047619047619 +8 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 8 9000 4.1692393770084735 95.70212765957447 +9 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 8 10000 5.027984232977032 95.77 +10 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 8 11000 6.0968318157643075 95.77 +11 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 8 12000 7.051064600273967 95.76 +12 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 8 13000 7.226595291718841 96.01 +13 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 8 14000 7.276074564233422 97.48 +14 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 8 15000 7.4755838479101655 98.46 +15 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 8 16000 7.394856667369604 99.07 +16 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 8 17000 7.459035102128983 98.31 +17 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 8 18000 7.495460703521967 97.63 +18 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 8 19000 7.479616451263428 97.45 +19 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 8 20000 7.447106442004443 97.45 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 9 2000 -0.152609384059906 97.15 +2 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 9 3000 2.004940494398276 98.1 +3 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 9 4000 3.3392293902977213 96.41463414634147 +4 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 9 5000 3.9495912826145596 93.62264150943396 +5 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 9 6000 4.517225810501259 92.546875 +6 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 9 7000 4.848400510301192 92.70666666666666 +7 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 9 8000 5.159681770820604 92.62790697674419 +8 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 9 9000 5.332991837795514 93.39583333333333 +9 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 9 10000 5.953502050004899 94.23 +10 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 9 11000 6.709970009885728 93.24 +11 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 9 12000 7.079162167273462 93.24 +12 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 9 13000 7.281057110093534 93.04 +13 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 9 14000 7.408379979729652 95.3 +14 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 9 15000 7.440449381023646 96.69 +15 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 9 16000 7.337198135629296 96.43 +16 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 9 17000 7.446303121075034 95.54 +17 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 9 18000 7.579947272613644 95.32 +18 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 9 19000 7.417809358760715 95.32 +19 SAC 2 2 0 True 0 0 [0,0] 0.05 10 1 0.0 1.0 1 9 20000 7.430626049861312 94.94 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 0 2000 -3.3477049499750136 96.65 +2 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 0 3000 -2.67111852367719 97.76666666666667 +3 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 0 4000 -0.4429823509076746 96.39024390243902 +4 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 0 5000 2.059364453667686 78.82539682539682 +5 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 0 6000 3.45887116307304 71.25 +6 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 0 7000 3.9863925878841853 72.16494845360825 +7 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 0 8000 5.133562170565129 69.74 +8 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 0 9000 6.552637500166893 68.54 +9 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 0 10000 7.348825080394745 67.68 +10 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 0 11000 7.566782011836767 66.86 +11 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 0 12000 7.674102166518569 73.44 +12 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 0 13000 7.617258865386248 77.93 +13 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 0 14000 7.610124039947987 84.01 +14 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 0 15000 7.6796439406275745 87.02 +15 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 0 16000 7.501976782083512 87.51 +16 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 0 17000 7.500371544659138 88.02 +17 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 0 18000 7.366779646277427 87.5 +18 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 0 19000 7.204744714945555 86.25 +19 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 0 20000 7.192874855846167 86.43 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 1 2000 -5.649501468241215 100.0 +2 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 1 3000 -4.418090064326922 98.76666666666667 +3 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 1 4000 -1.5598341403972535 94.64285714285714 +4 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 1 5000 0.8937107416490714 82.85 +5 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 1 6000 2.7429147484462435 72.51219512195122 +6 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 1 7000 3.340735299202303 72.39583333333333 +7 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 1 8000 4.537350212633609 72.16 +8 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 1 9000 5.833421991169453 71.21 +9 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 1 10000 7.145833925008774 69.42 +10 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 1 11000 7.459354734569788 69.83 +11 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 1 12000 7.6930150221288205 72.56 +12 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 1 13000 7.608196577802301 76.77 +13 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 1 14000 7.6027882810682055 80.55 +14 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 1 15000 7.761997758373618 83.08 +15 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 1 16000 7.542699755504727 83.07 +16 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 1 17000 7.61662404678762 81.98 +17 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 1 18000 7.454058018401265 83.27 +18 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 1 19000 7.249409743770957 83.73 +19 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 1 20000 7.194587181732058 84.12 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 2 2000 -5.17392952144146 100.0 +2 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 2 3000 -1.5933609840369993 96.70967741935483 +3 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 2 4000 1.580701274531228 81.44897959183673 +4 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 2 5000 2.9924882668715256 76.8 +5 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 2 6000 3.4835040316377817 78.77631578947368 +6 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 2 7000 3.9872780035385924 78.65168539325843 +7 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 2 8000 4.451704645901918 79.45 +8 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 2 9000 5.986491978317499 77.73 +9 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 2 10000 7.024845319539309 77.42 +10 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 2 11000 7.414677414447069 78.06 +11 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 2 12000 7.479622462689877 80.98 +12 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 2 13000 7.522784421890974 84.1 +13 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 2 14000 7.480271476656198 85.37 +14 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 2 15000 7.538205311000347 86.5 +15 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 2 16000 7.7031037132442 85.69 +16 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 2 17000 7.53973624035716 86.47 +17 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 2 18000 7.595187601596117 84.46 +18 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 2 19000 7.406328440010547 80.99 +19 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 2 20000 7.306179384589195 81.53 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 3 2000 -5.366040134429932 100.0 +2 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 3 3000 -2.1813469837109247 97.73333333333333 +3 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 3 4000 0.6499561809680678 90.9090909090909 +4 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 3 5000 2.387604512762828 81.18032786885246 +5 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 3 6000 3.210506121895901 80.87671232876713 +6 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 3 7000 3.72225367198033 83.16666666666667 +7 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 3 8000 3.9633711602618087 84.95744680851064 +8 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 3 9000 4.860277342125773 85.8 +9 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 3 10000 6.115094204321504 85.12 +10 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 3 11000 7.232169664129615 84.18 +11 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 3 12000 7.282734820172191 85.55 +12 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 3 13000 7.396055868193507 88.53 +13 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 3 14000 7.471142768040299 91.73 +14 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 3 15000 7.403364525288343 92.32 +15 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 3 16000 7.455006655901671 92.37 +16 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 3 17000 7.685096621513367 90.91 +17 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 3 18000 7.43244385778904 90.97 +18 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 3 19000 7.516778030991555 88.86 +19 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 3 20000 7.413941736370325 87.48 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 4 2000 1.231177044659853 100.0 +2 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 4 3000 3.166446948243726 95.06451612903226 +3 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 4 4000 4.537765986472368 79.26 +4 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 4 5000 5.367189426697902 73.34328358208955 +5 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 4 6000 5.727943824669894 70.23529411764706 +6 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 4 7000 5.866947032200794 72.71875 +7 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 4 8000 6.493740356862545 72.05 +8 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 4 9000 7.039959288835526 71.48 +9 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 4 10000 7.249956435412169 72.67 +10 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 4 11000 7.386200331747532 74.15 +11 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 4 12000 7.629731004014611 79.53 +12 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 4 13000 7.536256069540977 84.79 +13 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 4 14000 7.468295614272356 88.24 +14 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 4 15000 7.550507990568876 91.3 +15 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 4 16000 7.595726587623358 90.59 +16 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 4 17000 7.471666584610939 90.84 +17 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 4 18000 7.492833743840456 87.07 +18 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 4 19000 7.320896414220333 85.08 +19 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 4 20000 7.272704549729824 85.77 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 5 2000 -4.740732622146607 100.0 +2 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 5 3000 -1.1727175146341324 97.26666666666667 +3 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 5 4000 1.8222997281700373 82.79166666666667 +4 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 5 5000 3.0235945584755095 77.96825396825396 +5 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 5 6000 3.678239278992017 78.86666666666666 +6 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 5 7000 4.1571917708876525 80.84883720930233 +7 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 5 8000 4.453526835422963 82.63541666666667 +8 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 5 9000 5.634599045366048 81.45 +9 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 5 10000 7.055237418860197 79.91 +10 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 5 11000 7.2321304373443125 80.66 +11 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 5 12000 7.353234359323978 84.66 +12 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 5 13000 7.528417634963989 88.7 +13 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 5 14000 7.495676065087318 91.14 +14 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 5 15000 7.462748550772667 92.34 +15 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 5 16000 7.463142650574445 93.36 +16 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 5 17000 7.650906562209129 93.56 +17 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 5 18000 7.414826671630144 94.12 +18 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 5 19000 7.480984657555819 94.73 +19 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 5 20000 7.301182206869125 94.14 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 6 2000 0.29696482717990874 100.0 +2 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 6 3000 2.1139275963107744 99.5 +3 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 6 4000 3.8892109021544456 82.625 +4 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 6 5000 5.079360479305328 70.33802816901408 +5 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 6 6000 5.384362354523995 70.18823529411765 +6 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 6 7000 5.5628150833460195 72.03125 +7 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 6 8000 5.953348656445741 73.15 +8 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 6 9000 6.847772106379271 73.02 +9 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 6 10000 7.246008070856333 71.47 +10 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 6 11000 7.445875460207462 74.71 +11 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 6 12000 7.647735496684909 78.97 +12 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 6 13000 7.561909991428256 84.72 +13 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 6 14000 7.419349749311805 89.34 +14 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 6 15000 7.4698383998870845 91.21 +15 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 6 16000 7.6627335421741005 92.96 +16 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 6 17000 7.543119265735149 90.76 +17 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 6 18000 7.509603453576565 90.05 +18 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 6 19000 7.370730211734772 89.99 +19 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 6 20000 7.233952091038227 87.69 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 7 2000 -5.060379935801029 100.0 +2 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 7 3000 -2.103316662212213 98.83333333333333 +3 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 7 4000 0.633537929166447 90.68181818181819 +4 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 7 5000 2.6384813038166612 76.671875 +5 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 7 6000 3.3290237623609995 78.3157894736842 +6 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 7 7000 3.7787766561939797 80.14942528735632 +7 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 7 8000 4.269642783460593 80.70707070707071 +8 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 7 9000 5.847001513466239 77.15 +9 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 7 10000 7.0422378032654525 76.59 +10 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 7 11000 7.343252161368728 76.88 +11 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 7 12000 7.421478635445237 79.75 +12 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 7 13000 7.558077696338296 85.19 +13 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 7 14000 7.530851738676429 88.79 +14 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 7 15000 7.5956224253773685 89.11 +15 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 7 16000 7.635159336552024 88.82 +16 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 7 17000 7.495014047399163 88.75 +17 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 7 18000 7.523251652643085 89.44 +18 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 7 19000 7.3487237413972615 87.96 +19 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 7 20000 7.246742195263505 87.63 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 8 2000 -1.3019678726792336 100.0 +2 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 8 3000 0.5891571400066217 98.56666666666666 +3 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 8 4000 2.7611262288106526 86.47826086956522 +4 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 8 5000 4.409287619024095 70.01408450704226 +5 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 8 6000 4.809063946895571 71.51807228915662 +6 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 8 7000 4.983787485251301 72.85263157894737 +7 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 8 8000 5.897142907157541 72.65 +8 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 8 9000 6.809279952421784 70.83 +9 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 8 10000 7.238801768347621 71.26 +10 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 8 11000 7.422288225293159 73.67 +11 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 8 12000 7.592953066453338 77.35 +12 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 8 13000 7.567274255305529 82.43 +13 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 8 14000 7.546839514672756 87.91 +14 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 8 15000 7.459653750658036 90.26 +15 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 8 16000 7.654162168055773 90.71 +16 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 8 17000 7.4878582359850405 91.08 +17 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 8 18000 7.473560735136271 92.59 +18 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 8 19000 7.344547839909792 91.52 +19 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 8 20000 7.196957683712244 90.28 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 9 2000 -3.19961806088686 100.0 +2 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 9 3000 -0.5512308305309664 96.61290322580645 +3 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 9 4000 2.268921874463558 80.44897959183673 +4 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 9 5000 3.887957929850441 67.75342465753425 +5 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 9 6000 4.380794110631242 70.27058823529411 +6 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 9 7000 4.675861914719765 72.76041666666667 +7 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 9 8000 5.520298333391548 73.47 +8 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 9 9000 6.57298560552299 73.47 +9 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 9 10000 7.266279831156135 73.47 +10 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 9 11000 7.442100987061858 75.45 +11 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 9 12000 7.641886773109436 78.74 +12 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 9 13000 7.5789125101268295 85.17 +13 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 9 14000 7.568988925367594 90.11 +14 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 9 15000 7.588681897521019 91.25 +15 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 9 16000 7.6306933265924455 91.13 +16 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 9 17000 7.569630425125361 90.12 +17 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 9 18000 7.610726455450058 87.48 +18 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 9 19000 7.438710794895887 86.75 +19 SAC 2 2 0 True 0 0 [0,0] 0.1 10 1 0.0 1.0 1 9 20000 7.25108702480793 88.95 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 0 2000 -1.8862081527709962 100.0 +2 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 0 3000 0.8050708314951729 88.05882352941177 +3 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 0 4000 4.534216370619833 49.775 +4 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 0 5000 7.847951437830925 13.59 +5 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 0 6000 7.848577172756195 15.88 +6 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 0 7000 7.63240812689066 22.42 +7 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 0 8000 7.539004011452198 28.51 +8 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 0 9000 7.413934484422207 34.77 +9 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 0 10000 7.335608338862658 40.83 +10 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 0 11000 7.288773315697909 46.83 +11 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 0 12000 7.474953061491251 49.76 +12 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 0 13000 7.615466712862253 48.92 +13 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 0 14000 7.735840111225843 44.97 +14 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 0 15000 7.484529003500938 41.95 +15 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 0 16000 7.686029303371907 38.45 +16 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 0 17000 7.487768736332655 36.1 +17 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 0 18000 7.466642424464226 33.55 +18 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 0 19000 7.5746003496646885 34.67 +19 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 0 20000 7.197969994843006 37.36 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 1 2000 -5.722899484634399 100.0 +2 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 1 3000 -5.67494764328003 100.0 +3 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 1 4000 -5.566308343410492 100.0 +4 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 1 5000 -5.332747980075724 98.0 +5 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 1 6000 -3.5740049863234162 93.71875 +6 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 1 7000 0.7237647368013859 67.74 +7 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 1 8000 7.79805888146162 17.09 +8 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 1 9000 7.566834685802459 11.03 +9 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 1 10000 7.554719601273536 12.45 +10 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 1 11000 7.5861089462041855 19.78 +11 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 1 12000 7.6660764354467394 27.75 +12 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 1 13000 7.506869242638349 36.46 +13 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 1 14000 7.689497865587473 45.11 +14 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 1 15000 7.342805190384388 53.79 +15 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 1 16000 7.212903683334589 62.67 +16 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 1 17000 7.268200797736645 71.01 +17 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 1 18000 7.293846687227488 78.96 +18 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 1 19000 7.299013384878635 85.66 +19 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 1 20000 7.226413491368294 88.77 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 2 2000 -5.722899484634399 100.0 +2 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 2 3000 -5.01824152469635 100.0 +3 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 2 4000 0.7289295168751377 67.66101694915254 +4 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 2 5000 7.213194614350796 21.99 +5 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 2 6000 7.8045504656434055 13.46 +6 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 2 7000 7.550853794515133 15.21 +7 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 2 8000 7.411525172293186 19.12 +8 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 2 9000 7.498352069854736 25.31 +9 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 2 10000 7.603081729859114 29.71 +10 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 2 11000 7.626490402817726 35.42 +11 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 2 12000 7.537922002226114 36.69 +12 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 2 13000 7.620362444967031 36.45 +13 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 2 14000 7.640531334728003 40.05 +14 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 2 15000 7.445891966074705 38.4 +15 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 2 16000 7.574721005409956 38.77 +16 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 2 17000 7.466860307455063 41.14 +17 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 2 18000 7.094312513172627 39.51 +18 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 2 19000 6.998410175442696 42.45 +19 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 2 20000 7.430831015706063 38.2 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 3 2000 -2.2905775547027587 100.0 +2 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 3 3000 2.8195354772938623 66.62222222222222 +3 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 3 4000 7.389492147862911 18.81 +4 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 3 5000 7.871174047589302 15.42 +5 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 3 6000 7.839865258932114 20.43 +6 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 3 7000 7.548184940963983 24.44 +7 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 3 8000 7.473929534107446 30.82 +8 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 3 9000 7.390051954090596 34.9 +9 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 3 10000 7.503411957770586 34.13 +10 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 3 11000 7.568082220107317 34.39 +11 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 3 12000 7.764175082147122 32.72 +12 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 3 13000 7.475373490303755 33.09 +13 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 3 14000 7.7284668040275575 34.86 +14 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 3 15000 7.473262668699026 34.43 +15 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 3 16000 7.601550921648741 35.05 +16 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 3 17000 7.324671596884728 32.13 +17 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 3 18000 7.0313722224533555 32.36 +18 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 3 19000 7.166087500303984 34.08 +19 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 3 20000 7.355107343494892 37.29 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 4 2000 -2.7459045529365538 100.0 +2 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 4 3000 0.9280289600000662 87.47058823529412 +3 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 4 4000 4.711843144962157 45.91954022988506 +4 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 4 5000 7.784486718326807 15.39 +5 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 4 6000 7.9826534232497215 19.65 +6 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 4 7000 7.826879838854074 24.78 +7 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 4 8000 7.562700390815735 30.36 +8 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 4 9000 7.4304136653244495 34.83 +9 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 4 10000 7.44576445132494 39.96 +10 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 4 11000 7.327304866462946 42.49 +11 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 4 12000 7.433417257666588 44.03 +12 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 4 13000 7.600569139122963 40.31 +13 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 4 14000 7.643885030150414 37.5 +14 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 4 15000 7.462635440826416 40.25 +15 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 4 16000 7.676878886818886 36.06 +16 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 4 17000 7.633715987205505 36.7 +17 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 4 18000 7.448037182688713 31.77 +18 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 4 19000 7.554444598257541 35.3 +19 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 4 20000 7.171096696853637 36.66 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 5 2000 -5.511507607996464 100.0 +2 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 5 3000 -2.9120647067825 97.5 +3 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 5 4000 2.373214276973158 62.171875 +4 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 5 5000 7.79090188100934 12.81 +5 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 5 6000 7.583575259894133 11.17 +6 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 5 7000 7.485366955548525 14.86 +7 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 5 8000 7.513601730316878 20.53 +8 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 5 9000 7.4937528151273725 26.76 +9 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 5 10000 7.602302478104829 31.09 +10 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 5 11000 7.523419738709927 34.25 +11 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 5 12000 7.5384913489222525 39.74 +12 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 5 13000 7.677395249307156 39.89 +13 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 5 14000 7.475816418379545 41.19 +14 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 5 15000 7.407323991805315 43.13 +15 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 5 16000 7.551475808471441 40.98 +16 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 5 17000 7.187803554236889 40.09 +17 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 5 18000 6.97186305731535 38.05 +18 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 5 19000 7.300425242036581 36.81 +19 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 5 20000 7.33710038408637 37.63 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 6 2000 -3.249888621625446 92.42857142857143 +2 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 6 3000 1.2642004524285977 76.56410256410257 +3 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 6 4000 4.634837059284512 42.10526315789474 +4 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 6 5000 7.821624441593886 13.83 +5 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 6 6000 7.746355017125606 16.47 +6 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 6 7000 7.48006516456604 22.45 +7 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 6 8000 7.459156271070242 27.18 +8 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 6 9000 7.452570190131664 33.26 +9 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 6 10000 7.468687061667442 36.57 +10 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 6 11000 7.668894867151976 33.95 +11 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 6 12000 7.692303963303566 31.52 +12 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 6 13000 7.609696515798569 29.78 +13 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 6 14000 7.667031039595604 32.17 +14 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 6 15000 7.576620071530342 33.09 +15 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 6 16000 7.564100780338049 35.63 +16 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 6 17000 7.253748523741961 35.31 +17 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 6 18000 7.068406400084496 30.81 +18 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 6 19000 7.397706113308669 32.82 +19 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 6 20000 7.492337888777256 31.66 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 7 2000 -5.697835540771484 100.0 +2 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 7 3000 -0.616021956716265 85.17142857142858 +3 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 7 4000 4.056295066740778 44.24444444444445 +4 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 7 5000 7.770264280438423 15.91 +5 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 7 6000 8.0519322578609 19.65 +6 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 7 7000 7.7326435515284535 25.17 +7 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 7 8000 7.593152420371771 31.4 +8 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 7 9000 7.460193939059973 36.4 +9 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 7 10000 7.474687271863222 41.08 +10 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 7 11000 7.408378434926272 44.08 +11 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 7 12000 7.460832555741072 42.79 +12 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 7 13000 7.501352113187313 45.79 +13 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 7 14000 7.644109554588795 45.72 +14 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 7 15000 7.73692823395133 44.22 +15 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 7 16000 7.480259595513344 43.08 +16 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 7 17000 7.7029584603011605 36.37 +17 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 7 18000 7.552779046595097 34.76 +18 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 7 19000 7.49625326693058 37.91 +19 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 7 20000 7.52086599573493 37.65 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 8 2000 0.06775925131071181 91.0952380952381 +2 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 8 3000 3.0850504979491236 74.6 +3 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 8 4000 6.08580334931612 34.94 +4 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 8 5000 7.860105338990689 15.15 +5 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 8 6000 7.8746232676506045 19.75 +6 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 8 7000 7.733929405510426 26.74 +7 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 8 8000 7.551976200938225 32.89 +8 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 8 9000 7.442406873553991 37.17 +9 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 8 10000 7.351332637518644 41.61 +10 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 8 11000 7.5207131417095665 42.95 +11 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 8 12000 7.423573211580515 39.87 +12 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 8 13000 7.64360751375556 39.46 +13 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 8 14000 7.659621994495392 38.52 +14 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 8 15000 7.605424227714539 35.38 +15 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 8 16000 7.636247434020042 33.23 +16 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 8 17000 7.421739491224289 33.07 +17 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 8 18000 7.5948199644684795 32.62 +18 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 8 19000 7.1942502987384795 32.25 +19 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 8 20000 7.1476364187896255 30.06 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 9 2000 1.8325671806931496 98.9 +2 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 9 3000 3.352498264873729 87.8529411764706 +3 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 9 4000 5.936384876467744 40.795918367346935 +4 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 9 5000 7.833481531143189 13.42 +5 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 9 6000 7.973974343836307 17.79 +6 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 9 7000 7.615442841649055 23.58 +7 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 9 8000 7.469037293195725 30.19 +8 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 9 9000 7.5190662406384945 36.7 +9 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 9 10000 7.41771211490035 41.43 +10 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 9 11000 7.475077098309994 43.86 +11 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 9 12000 7.421937486827374 45.07 +12 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 9 13000 7.578343826681375 40.87 +13 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 9 14000 7.422074438631535 40.15 +14 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 9 15000 7.6037848028540616 37.2 +15 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 9 16000 7.63999874562025 38.16 +16 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 9 17000 7.378684556484222 35.39 +17 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 9 18000 7.519851326644421 35.87 +18 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 9 19000 7.098082813769579 36.05 +19 SAC 2 2 0 True 0 0 [0,0] 0.25 10 1 0.0 1.0 1 9 20000 6.990610994249582 36.4 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 0 2000 0.0576970636844635 97.45 +2 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 0 3000 2.8050574757158757 74.375 +3 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 0 4000 6.118364988565445 31.99 +4 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 0 5000 7.571021899833518 8.44915254237288 +5 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 0 6000 7.4123590111732485 7.92 +6 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 0 7000 7.585117661129169 8.211382113821138 +7 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 0 8000 7.023110069627837 7.811023622047244 +8 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 0 9000 7.426795280641979 8.606837606837606 +9 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 0 10000 7.705789420787279 9.0 +10 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 0 11000 7.480538348812575 9.220183486238533 +11 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 0 12000 7.049416632224352 8.495726495726496 +12 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 0 13000 7.42394827866773 9.174311926605505 +13 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 0 14000 7.072537884382265 8.982142857142858 +14 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 0 15000 7.507727529248621 8.504273504273504 +15 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 0 16000 7.047763625425952 8.982142857142858 +16 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 0 17000 6.384359766502638 8.972972972972974 +17 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 0 18000 7.04558228940334 9.433962264150944 +18 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 0 19000 7.319016139064215 8.867256637168142 +19 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 0 20000 7.614396174164379 9.794117647058824 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 1 2000 0.28944812119007113 95.7 +2 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 1 3000 3.7956206139463644 57.53846153846154 +3 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 1 4000 7.739370711798807 9.757281553398059 +4 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 1 5000 7.343437614168708 7.897637795275591 +5 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 1 6000 7.457846129973103 7.7952755905511815 +6 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 1 7000 7.407959282642505 8.278688524590164 +7 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 1 8000 7.108280196666717 8.0 +8 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 1 9000 7.75946420910103 8.866071428571429 +9 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 1 10000 7.455506806269936 8.721739130434782 +10 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 1 11000 7.313976301697263 8.736842105263158 +11 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 1 12000 7.0958748161792755 9.485714285714286 +12 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 1 13000 7.105886901110674 8.955752212389381 +13 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 1 14000 7.286341497592167 8.84070796460177 +14 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 1 15000 7.777555867135525 10.14 +15 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 1 16000 6.922967610515166 9.392523364485982 +16 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 1 17000 6.415164215975449 8.38655462184874 +17 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 1 18000 6.932138991706512 9.735294117647058 +18 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 1 19000 7.563181387117276 9.634615384615385 +19 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 1 20000 7.306706318401155 9.523809523809524 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 2 2000 1.0732043030716123 91.76190476190476 +2 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 2 3000 3.8057282263040544 59.82 +3 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 2 4000 7.659611842632294 10.09 +4 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 2 5000 7.330022511264635 7.936507936507937 +5 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 2 6000 7.671624648074309 8.35 +6 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 2 7000 7.169445538570073 8.272727272727273 +7 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 2 8000 7.286172982999834 8.432203389830509 +8 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 2 9000 7.351948217328252 8.60344827586207 +9 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 2 10000 7.601646546884017 9.072727272727272 +10 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 2 11000 7.527818595821207 9.163636363636364 +11 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 2 12000 7.08778135325307 9.36448598130841 +12 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 2 13000 7.1510549101317045 9.261682242990654 +13 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 2 14000 7.1674669960748805 9.766990291262136 +14 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 2 15000 7.668297062223813 9.452830188679245 +15 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 2 16000 7.0378873962582205 8.771929824561404 +16 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 2 17000 6.3949900878741675 8.849557522123893 +17 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 2 18000 6.987726318954241 9.831683168316832 +18 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 2 19000 7.359511733931654 9.754901960784315 +19 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 2 20000 7.5937546616792675 10.12 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 3 2000 -0.36304014662037726 86.65217391304348 +2 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 3 3000 1.8973867750980637 67.86363636363636 +3 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 3 4000 7.432292037308216 11.96 +4 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 3 5000 7.49752989238944 8.256198347107437 +5 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 3 6000 7.494819258572534 7.7890625 +6 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 3 7000 7.256695803560194 8.172131147540984 +7 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 3 8000 7.274176280538575 8.428571428571429 +8 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 3 9000 7.335000516039081 8.867256637168142 +9 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 3 10000 7.686629846159901 8.955357142857142 +10 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 3 11000 7.43369698325793 8.308333333333334 +11 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 3 12000 7.11379085784709 9.185185185185185 +12 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 3 13000 7.1367678969566315 9.026785714285714 +13 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 3 14000 7.340620548106157 9.461538461538462 +14 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 3 15000 7.623809416057928 9.537735849056604 +15 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 3 16000 6.898786103417134 8.586206896551724 +16 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 3 17000 6.4381297889376885 8.453781512605042 +17 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 3 18000 7.1493189922560045 9.289719626168225 +18 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 3 19000 7.35413877315381 9.852941176470589 +19 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 3 20000 7.598889067335036 9.669902912621358 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 4 2000 -3.7137835904955865 99.1 +2 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 4 3000 -1.0445610338991338 88.03030303030303 +3 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 4 4000 4.321927946867402 41.22680412371134 +4 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 4 5000 7.730726535683093 8.678260869565218 +5 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 4 6000 7.412017303475967 7.6692307692307695 +6 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 4 7000 7.552864651455254 8.237704918032787 +7 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 4 8000 7.028722677202452 7.944444444444445 +8 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 4 9000 7.467539232413648 8.44915254237288 +9 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 4 10000 7.750500761302171 8.849557522123893 +10 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 4 11000 7.459505724432194 8.823008849557523 +11 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 4 12000 7.0672209808784245 8.849557522123893 +12 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 4 13000 7.347437898917445 8.60344827586207 +13 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 4 14000 7.085287738003228 8.833333333333334 +14 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 4 15000 7.449119746958444 9.091743119266056 +15 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 4 16000 7.095133230347058 8.663793103448276 +16 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 4 17000 6.5145978987717825 8.378151260504202 +17 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 4 18000 7.013702860745517 9.118181818181819 +18 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 4 19000 7.375389358707678 9.392523364485982 +19 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 4 20000 7.681593686623393 9.377358490566039 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 5 2000 -4.975560468435288 95.9 +2 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 5 3000 -0.6828208534341109 78.78947368421052 +3 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 5 4000 7.100928924381733 16.81 +4 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 5 5000 7.614715497024724 8.147540983606557 +5 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 5 6000 7.498402256751433 7.84375 +6 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 5 7000 7.31288991526502 8.163934426229508 +7 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 5 8000 7.213150541613421 7.905511811023622 +8 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 5 9000 7.387610651983702 8.24793388429752 +9 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 5 10000 7.560468401631405 8.629310344827585 +10 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 5 11000 7.543857464823154 9.155963302752294 +11 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 5 12000 7.050522931620606 8.598290598290598 +12 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 5 13000 7.141687786013915 8.586206896551724 +13 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 5 14000 7.025368136276892 9.100917431192661 +14 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 5 15000 7.966721129086283 9.37037037037037 +15 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 5 16000 6.890193418182176 8.60344827586207 +16 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 5 17000 6.475526701252 8.361344537815127 +17 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 5 18000 7.03479198659105 8.928571428571429 +18 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 5 19000 7.659924101192974 9.776699029126213 +19 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 5 20000 7.254806867241859 9.9 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 6 2000 -4.860856954753399 95.85 +2 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 6 3000 2.2330811265504584 56.283018867924525 +3 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 6 4000 7.744196394202756 9.911764705882353 +4 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 6 5000 7.342458741273731 7.828125 +5 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 6 6000 7.524212987192215 8.07258064516129 +6 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 6 7000 7.35494319654879 8.139344262295081 +7 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 6 8000 7.144781875610351 8.782608695652174 +8 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 6 9000 7.513953602207558 8.901785714285714 +9 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 6 10000 7.445565393485061 9.192660550458715 +10 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 6 11000 7.63084264844656 9.25 +11 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 6 12000 6.9371235831924105 8.68695652173913 +12 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 6 13000 7.108527958641449 8.341666666666667 +13 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 6 14000 7.260772307982316 8.891891891891891 +14 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 6 15000 7.864762073755264 10.11 +15 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 6 16000 6.878092082582902 9.355140186915888 +16 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 6 17000 6.519731876058657 8.188524590163935 +17 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 6 18000 7.000243743994962 8.678260869565218 +18 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 6 19000 7.631620917680128 9.462264150943396 +19 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 6 20000 7.2806214212792595 9.718446601941748 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 7 2000 -2.1384351015090943 100.0 +2 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 7 3000 0.6590705189634772 87.61764705882354 +3 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 7 4000 4.586642477175464 43.380434782608695 +4 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 7 5000 7.861424090810444 8.73913043478261 +5 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 7 6000 7.3290303709415285 7.653846153846154 +6 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 7 7000 7.595072368544246 8.007936507936508 +7 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 7 8000 7.060325024649501 7.8125 +8 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 7 9000 7.427404687801997 8.3 +9 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 7 10000 7.766372396496305 8.74561403508772 +10 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 7 11000 7.424082949354842 9.045045045045045 +11 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 7 12000 7.09371049557112 8.823008849557523 +12 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 7 13000 7.3191192052533145 8.858407079646017 +13 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 7 14000 7.056765088438988 9.118181818181819 +14 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 7 15000 7.469878352150835 8.543103448275861 +15 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 7 16000 7.067670661629292 8.824561403508772 +16 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 7 17000 6.4690533694008305 8.60344827586207 +17 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 7 18000 7.094201132789388 9.063063063063064 +18 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 7 19000 7.245890606343746 10.01 +19 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 7 20000 7.659118307279606 9.754901960784315 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 8 2000 -1.829936867952347 95.3 +2 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 8 3000 1.696437557296055 72.78048780487805 +3 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 8 4000 6.143526721000671 27.86 +4 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 8 5000 7.6302559044340565 8.663793103448276 +5 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 8 6000 7.4082130484581 7.992 +6 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 8 7000 7.56786117421799 8.221311475409836 +7 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 8 8000 6.964507415769546 8.105691056910569 +8 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 8 9000 7.492224009152045 8.771929824561404 +9 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 8 10000 7.627530552446842 8.612068965517242 +10 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 8 11000 7.423165137480412 8.9375 +11 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 8 12000 7.1610754222498025 9.211009174311927 +12 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 8 13000 7.328917648148748 8.761061946902656 +13 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 8 14000 7.1124566714320565 8.920353982300885 +14 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 8 15000 7.509247489399829 8.483050847457626 +15 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 8 16000 7.010110945839967 8.892857142857142 +16 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 8 17000 6.50925276692458 7.905511811023622 +17 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 8 18000 7.080838151668248 8.74561403508772 +18 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 8 19000 7.382712706513361 9.155963302752294 +19 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 8 20000 7.339611931103412 9.383177570093459 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 9 2000 -2.4848313689231873 97.25 +2 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 9 3000 0.47478199345724925 85.65714285714286 +3 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 9 4000 7.195502868890762 17.12 +4 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 9 5000 7.576056223762922 8.264462809917354 +5 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 9 6000 7.498444433991365 7.866141732283465 +6 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 9 7000 7.436901090637086 7.9523809523809526 +7 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 9 8000 7.1121260741206465 8.188524590163935 +8 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 9 9000 7.42979848732551 8.366666666666667 +9 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 9 10000 7.565088055112906 8.780701754385966 +10 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 9 11000 7.459018558800757 8.927927927927929 +11 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 9 12000 7.166920383598494 8.730434782608695 +12 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 9 13000 7.156499960132547 9.018018018018019 +13 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 9 14000 7.196230711926401 8.88495575221239 +14 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 9 15000 7.7516993343830105 10.44 +15 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 9 16000 6.981964115663009 9.063636363636364 +16 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 9 17000 6.3013351471651164 9.485714285714286 +17 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 9 18000 7.075170015117952 8.883928571428571 +18 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 9 19000 7.33146323889494 10.71 +19 SAC 2 2 0 True 0 0 [0,0] 0.5 10 1 0.0 1.0 1 9 20000 7.499004864692688 10.14 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 0 2000 -1.534208784500758 82.45833333333333 +2 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 0 3000 -0.5123511601138759 80.51351351351352 +3 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 0 4000 -0.3282066618020718 75.5 +4 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 0 5000 0.6528551353924517 72.10144927536231 +5 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 0 6000 2.3569508147239686 59.65 +6 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 0 7000 7.505284694433212 10.82 +7 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 0 8000 7.117497346951411 7.7 +8 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 0 9000 7.288344244305178 7.201438848920863 +9 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 0 10000 6.869639663051252 6.876712328767123 +10 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 0 11000 7.280555563537698 6.572368421052632 +11 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 0 12000 7.379768347503334 6.622516556291391 +12 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 0 13000 6.881155459955335 6.2375 +13 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 0 14000 7.0683557803525865 6.320754716981132 +14 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 0 15000 7.155948641953195 6.337579617834395 +15 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 0 16000 6.735271261959541 6.079268292682927 +16 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 0 17000 6.482744367673383 5.847953216374269 +17 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 0 18000 7.175197119132067 6.461538461538462 +18 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 0 19000 6.9258224461227655 6.225 +19 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 0 20000 6.500034258833954 5.964285714285714 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 1 2000 -2.8277929544448854 100.0 +2 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 1 3000 1.912840671317522 69.67441860465117 +3 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 1 4000 7.101535508036614 10.74 +4 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 1 5000 7.1038978508789175 7.306569343065694 +5 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 1 6000 7.107619292115512 6.8493150684931505 +6 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 1 7000 6.961537949641546 6.673333333333333 +7 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 1 8000 7.2797555635932465 7.049295774647887 +8 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 1 9000 7.315989878836212 6.958041958041958 +9 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 1 10000 7.210393943252234 6.917241379310345 +10 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 1 11000 7.031570117599917 6.635761589403973 +11 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 1 12000 6.646819114307814 6.3164556962025316 +12 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 1 13000 7.544804821551685 7.063380281690141 +13 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 1 14000 6.26281643757619 6.030120481927711 +14 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 1 15000 6.884365125608287 6.565789473684211 +15 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 1 16000 7.282228636158096 6.993006993006993 +16 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 1 17000 6.6678799952452 6.384615384615385 +17 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 1 18000 6.774305732219251 6.51948051948052 +18 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 1 19000 7.211938927165505 6.802721088435374 +19 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 1 20000 7.296438786950144 6.972027972027972 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 2 2000 -0.4757707913716634 73.70370370370371 +2 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 2 3000 2.242915893976505 57.42307692307692 +3 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 2 4000 7.36414868614384 9.457943925233645 +4 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 2 5000 7.045558418250746 6.902777777777778 +5 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 2 6000 7.314000128032444 7.041958041958042 +6 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 2 7000 6.843718220194181 6.64 +7 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 2 8000 7.216152241660489 6.972222222222222 +8 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 2 9000 7.330572381405763 7.014084507042254 +9 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 2 10000 7.097244766091003 6.809523809523809 +10 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 2 11000 6.978173863490422 6.64 +11 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 2 12000 6.872294182808983 6.6158940397351 +12 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 2 13000 7.256643008944151 6.8175675675675675 +13 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 2 14000 6.362524912964483 6.198757763975156 +14 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 2 15000 7.024821541210016 6.666666666666667 +15 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 2 16000 7.183394844715412 6.986013986013986 +16 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 2 17000 6.659087329518561 6.555555555555555 +17 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 2 18000 6.858564790263272 6.671140939597316 +18 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 2 19000 7.242015465785717 6.924137931034482 +19 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 2 20000 7.205764071091072 7.006993006993007 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 3 2000 -3.803029691631144 89.0 +2 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 3 3000 2.4090102181352417 51.62068965517241 +3 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 3 4000 7.249900269868045 8.655172413793103 +4 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 3 5000 7.060877038048697 6.958041958041958 +5 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 3 6000 7.317203629101422 7.120567375886525 +6 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 3 7000 6.902042556206386 6.6866666666666665 +7 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 3 8000 7.1752441771380555 6.958041958041958 +8 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 3 9000 7.4072313797725755 7.070422535211268 +9 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 3 10000 7.0336513151861215 6.815068493150685 +10 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 3 11000 6.90320446210749 6.555555555555555 +11 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 3 12000 7.035104224345828 6.731543624161074 +12 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 3 13000 7.126680680626148 6.743243243243243 +13 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 3 14000 6.360896439647969 6.172839506172839 +14 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 3 15000 7.014855519637165 6.718120805369128 +15 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 3 16000 7.257743379869662 6.972027972027972 +16 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 3 17000 6.618656685149747 6.516339869281046 +17 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 3 18000 6.739755467846503 6.57516339869281 +18 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 3 19000 7.294536891517105 7.0 +19 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 3 20000 7.273640917970779 7.085106382978723 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 4 2000 -0.42651826414194977 86.63636363636364 +2 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 4 3000 3.1754354357719423 54.45454545454545 +3 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 4 4000 7.2939599701336455 9.514285714285714 +4 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 4 5000 7.037813452767654 7.056338028169014 +5 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 4 6000 7.326114540368739 7.063380281690141 +6 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 4 7000 6.8825038532416025 6.6466666666666665 +7 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 4 8000 7.160894562800725 6.9375 +8 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 4 9000 7.3329761294831695 7.042253521126761 +9 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 4 10000 7.0854961099673295 6.816326530612245 +10 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 4 11000 6.892195981976233 6.552631578947368 +11 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 4 12000 6.884675161618936 6.572368421052632 +12 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 4 13000 7.241531179563419 6.804054054054054 +13 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 4 14000 6.356276133971185 6.198757763975156 +14 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 4 15000 7.005869801181394 6.716216216216216 +15 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 4 16000 7.207344000915001 6.958620689655173 +16 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 4 17000 6.686947265092065 6.503267973856209 +17 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 4 18000 6.802246624309766 6.5855263157894735 +18 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 4 19000 7.316987613423003 6.944444444444445 +19 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 4 20000 7.13899648970571 6.875862068965517 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 5 2000 0.06373162269592285 99.2 +2 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 5 3000 4.298080774687104 50.71186440677966 +3 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 5 4000 7.304840352490683 9.355140186915888 +4 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 5 5000 7.099457482354982 7.142857142857143 +5 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 5 6000 7.31163184323781 7.070422535211268 +6 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 5 7000 6.821925199737675 6.565789473684211 +7 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 5 8000 7.24986316500039 6.931034482758621 +8 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 5 9000 7.381744763171169 7.014084507042254 +9 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 5 10000 6.986964480188869 6.738255033557047 +10 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 5 11000 6.9118629693984985 6.578947368421052 +11 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 5 12000 7.002625511707486 6.702702702702703 +12 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 5 13000 7.184017879938757 6.777027027027027 +13 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 5 14000 6.416946825789816 6.203703703703703 +14 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 5 15000 6.991527385405592 6.70945945945946 +15 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 5 16000 7.212325999589815 6.86986301369863 +16 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 5 17000 6.647579287107174 6.397435897435898 +17 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 5 18000 6.756343022475835 6.568627450980392 +18 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 5 19000 7.308285440598334 6.937062937062937 +19 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 5 20000 7.213005044953577 6.944827586206896 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 6 2000 -3.0710071467217945 92.57142857142857 +2 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 6 3000 2.301387272097848 54.163636363636364 +3 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 6 4000 7.314008890986442 11.18 +4 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 6 5000 7.169676556432847 7.18705035971223 +5 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 6 6000 7.084495190479984 6.828767123287672 +6 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 6 7000 6.902199495358755 6.704697986577181 +7 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 6 8000 7.2193665152622595 6.986111111111111 +8 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 6 9000 7.39636358449645 7.042553191489362 +9 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 6 10000 7.081998052473726 6.889655172413793 +10 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 6 11000 7.03815740386645 6.706666666666667 +11 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 6 12000 6.758003732465928 6.464516129032258 +12 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 6 13000 7.235920483527118 6.8493150684931505 +13 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 6 14000 6.408328276243269 6.204968944099379 +14 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 6 15000 6.947930003238829 6.6158940397351 +15 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 6 16000 7.219056385380405 6.993006993006993 +16 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 6 17000 6.718730846143538 6.458064516129032 +17 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 6 18000 6.786058213561773 6.552631578947368 +18 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 6 19000 7.17403720390229 6.802721088435374 +19 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 6 20000 7.361042675837664 7.035211267605634 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 7 2000 3.9178460376603264 56.542857142857144 +2 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 7 3000 5.682164649963379 29.04 +3 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 7 4000 7.2848722022591215 7.568181818181818 +4 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 7 5000 7.234290520350139 6.965277777777778 +5 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 7 6000 7.058204934710548 6.802721088435374 +6 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 7 7000 7.0248241200022505 6.794520547945205 +7 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 7 8000 7.316337030958122 7.042253521126761 +8 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 7 9000 7.137974005243549 6.863013698630137 +9 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 7 10000 7.028724827222376 6.751677852348993 +10 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 7 11000 6.971930674424297 6.546052631578948 +11 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 7 12000 7.292450359566458 6.896551724137931 +12 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 7 13000 6.601029383528764 6.388535031847134 +13 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 7 14000 6.490847918372717 6.217391304347826 +14 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 7 15000 7.233254079635326 7.0 +15 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 7 16000 6.94797642839035 6.697986577181208 +16 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 7 17000 6.585297400561663 6.423076923076923 +17 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 7 18000 7.1687196015069885 6.909722222222222 +18 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 7 19000 7.310113242516915 6.951388888888889 +19 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 7 20000 6.993821675511631 6.736486486486487 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 8 2000 -2.340465393933383 90.18181818181819 +2 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 8 3000 0.12741372616667496 78.94736842105263 +3 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 8 4000 6.84292183637619 14.57 +4 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 8 5000 7.278089350602758 7.881889763779528 +5 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 8 6000 7.293252210957664 7.185714285714286 +6 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 8 7000 6.947714665192086 6.691275167785235 +7 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 8 8000 7.068519572689109 6.835616438356165 +8 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 8 9000 7.468952917626926 7.185714285714286 +9 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 8 10000 7.172706579203372 6.986013986013986 +10 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 8 11000 7.04071735175664 6.691275167785235 +11 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 8 12000 6.760315735628651 6.3630573248407645 +12 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 8 13000 7.314777353385678 6.809523809523809 +13 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 8 14000 6.412557104119548 6.179012345679013 +14 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 8 15000 6.726218713374881 6.5 +15 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 8 16000 7.196625839019644 6.882758620689655 +16 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 8 17000 6.910490649425431 6.622516556291391 +17 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 8 18000 6.486112646572292 6.26875 +18 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 8 19000 7.263711222081349 6.855172413793103 +19 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 8 20000 7.339790689361679 7.013986013986014 +# training_iteration, algorithm, state_space_dim, action_space_dim, delay, make_denser, transition_noise, reward_noise, target_point, target_radius, state_space_max, action_space_max, action_loss_weight, time_unit, transition_dynamics_order, dummy_seed, timesteps_total, episode_reward_mean, episode_len_mean +1 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 9 2000 -4.381171464920044 93.14285714285714 +2 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 9 3000 1.162253588438034 61.958333333333336 +3 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 9 4000 7.096073636412621 11.1 +4 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 9 5000 7.075387580376683 7.5606060606060606 +5 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 9 6000 7.115120336717489 6.8231292517006805 +6 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 9 7000 7.032201150039426 6.802721088435374 +7 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 9 8000 7.201670741248462 6.923611111111111 +8 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 9 9000 7.293447052473788 7.006993006993007 +9 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 9 10000 7.153510353483003 6.896551724137931 +10 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 9 11000 7.02352850602952 6.629139072847682 +11 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 9 12000 6.700661273139297 6.350318471337579 +12 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 9 13000 7.425462106307903 6.986013986013986 +13 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 9 14000 6.29428190156454 6.085365853658536 +14 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 9 15000 6.840657303535861 6.542483660130719 +15 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 9 16000 7.276855198236612 6.965034965034965 +16 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 9 17000 6.720052051928736 6.490322580645161 +17 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 9 18000 6.838745147581921 6.622516556291391 +18 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 9 19000 7.093892941201055 6.72972972972973 +19 SAC 2 2 0 True 0 0 [0,0] 1.0 10 1 0.0 1.0 1 9 20000 7.351263526206215 6.993055555555555 diff --git a/tests/files/mdpp_12744267_SAC_target_radius/sac_move_to_a_point_target_radius_eval.csv b/tests/files/mdpp_12744267_SAC_target_radius/sac_move_to_a_point_target_radius_eval.csv new file mode 100644 index 0000000..7793197 --- /dev/null +++ b/tests/files/mdpp_12744267_SAC_target_radius/sac_move_to_a_point_target_radius_eval.csv @@ -0,0 +1,10450 @@ +#HACK STRING EVAL +-0.618952751159668 100 +-3.4923582077026367 100 +-4.838714599609375 100 +-1.5983772277832031 100 +-2.868363380432129 100 +-1.1816415786743164 100 +-5.823403835296631 100 +0.22630786895751953 100 +-2.408757209777832 100 +-1.9021883010864258 100 +#HACK STRING EVAL +6.323272094130516 100 +5.183857709169388 100 +8.248822569847107 100 +10.559866324067116 100 +5.880604162812233 100 +10.08033874630928 100 +9.362829566001892 100 +8.86819675564766 100 +7.726491346955299 100 +9.510713934898376 100 +#HACK STRING EVAL +9.769597291946411 100 +8.671065613627434 100 +8.170224443078041 100 +4.996565118432045 100 +7.598379835486412 100 +11.035707771778107 100 +9.878391534090042 100 +7.653960466384888 100 +6.042459234595299 100 +6.804743990302086 100 +#HACK STRING EVAL +5.754450678825378 100 +7.629828557372093 100 +4.469289124011993 4 +7.321338921785355 100 +10.661088198423386 100 +9.556370794773102 100 +7.155925929546356 100 +7.531993716955185 100 +9.725087404251099 100 +2.8474096059799194 3 +#HACK STRING EVAL +6.486093670129776 100 +5.473917305469513 100 +8.255456864833832 100 +0.6811030954122543 100 +8.061189591884613 100 +5.76019012928009 100 +4.219133943319321 100 +7.509403929114342 100 +7.55734920501709 100 +1.4295799136161804 100 +#HACK STRING EVAL +7.624325454235077 100 +2.9802419543266296 100 +9.290683567523956 100 +5.813482463359833 100 +10.81063586473465 100 +7.748379200696945 100 +9.980774223804474 100 +6.8961257338523865 100 +1.7104887962341309 100 +5.711346864700317 100 +#HACK STRING EVAL +4.632042706012726 100 +5.151309072971344 100 +8.372318804264069 100 +10.45293614268303 100 +12.155558466911316 100 +2.0967501401901245 100 +12.25676143169403 100 +8.886090993881226 100 +8.215309113264084 100 +5.1826271414756775 100 +#HACK STRING EVAL +5.965293645858765 100 +3.9564163088798523 100 +2.5701504945755005 100 +3.244380474090576 100 +8.44815307855606 100 +6.9065205454826355 100 +6.777535080909729 100 +10.94428014755249 100 +8.898073822259903 100 +9.122014820575714 100 +#HACK STRING EVAL +7.742597162723541 100 +8.30836433172226 100 +5.8522955775260925 100 +1.7395698130130768 100 +7.789197027683258 100 +5.561614215373993 100 +2.3994871973991394 100 +6.811800241470337 100 +5.5399051904678345 100 +4.549964606761932 100 +#HACK STRING EVAL +8.44277560710907 100 +3.0049809217453003 100 +8.360286176204681 100 +7.73223739862442 100 +9.434574455022812 100 +12.605330407619476 100 +9.740712463855743 100 +6.984224081039429 100 +10.89188814163208 100 +5.507196605205536 100 +#HACK STRING EVAL +8.706120729446411 100 +8.76986312866211 100 +11.153232038021088 100 +7.352273941040039 100 +2.7304717302322388 100 +8.140499949455261 100 +8.818568587303162 100 +4.886470407247543 100 +3.09565669298172 100 +5.863429516553879 100 +#HACK STRING EVAL +4.810087561607361 100 +12.718968659639359 100 +9.651746273040771 100 +6.855310082435608 100 +11.086319744586945 100 +4.023548245429993 100 +0.7036203145980835 100 +5.50420880317688 100 +11.43659794330597 100 +9.518917560577393 100 +#HACK STRING EVAL +5.797106027603149 100 +10.256089270114899 100 +10.559244990348816 100 +4.099280774593353 100 +11.598754167556763 100 +2.771838128566742 100 +9.355754673480988 100 +5.1861292719841 100 +8.561014235019684 100 +8.467089533805847 100 +#HACK STRING EVAL +10.454358339309692 100 +9.328536331653595 100 +10.899350047111511 100 +5.0457605719566345 100 +8.481358796358109 100 +9.207206517457962 100 +8.2017280459404 100 +10.043535143136978 100 +5.317674994468689 100 +7.657705217599869 100 +#HACK STRING EVAL +7.937848627567291 100 +2.7883253693580627 100 +11.490831077098846 100 +4.037501931190491 100 +8.11913388967514 100 +8.46570748090744 100 +8.673076152801514 100 +9.239754378795624 100 +7.433223783969879 100 +12.05315363407135 100 +#HACK STRING EVAL +3.804786503314972 100 +6.029473721981049 100 +11.20130181312561 100 +8.151667058467865 100 +5.103249132633209 100 +12.992595911026001 100 +0.21890634298324585 100 +9.341115593910217 100 +0.9462153315544128 100 +7.238853871822357 100 +#HACK STRING EVAL +6.2103590071201324 100 +3.741077482700348 100 +10.233519196510315 100 +7.706679344177246 100 +8.733112514019012 100 +7.068768680095673 100 +7.8021827936172485 100 +8.737423479557037 100 +2.2188674807548523 100 +8.014431297779083 100 +#HACK STRING EVAL +4.610031545162201 100 +9.237768113613129 100 +9.200558483600616 100 +4.40588253736496 100 +9.157443344593048 100 +9.17119836807251 100 +8.978381037712097 100 +6.465941905975342 100 +4.518840074539185 100 +9.317073464393616 100 +#HACK STRING EVAL +4.040683776140213 100 +7.906050652265549 100 +6.707158595323563 100 +10.812875926494598 100 +6.655338883399963 100 +7.96708869934082 100 +6.563523024320602 100 +8.833887219429016 100 +7.6605225801467896 100 +3.628543049097061 100 +#HACK STRING EVAL +-3.7503671646118164 100 +-2.578728675842285 100 +-7.995953559875488 100 +-4.92095947265625 100 +-6.310798645019531 100 +-4.496591567993164 100 +-9.295823574066162 100 +1.1221237182617188 100 +-5.535251617431641 100 +-1.013864517211914 100 +#HACK STRING EVAL +6.514863278716803 31 +5.37152648717165 29 +8.395786479115486 100 +10.760380066931248 27 +6.0790004543960094 22 +10.227302744984627 100 +9.509793438017368 100 +9.015160717070103 100 +7.946458622813225 19 +9.706644058227539 26 +#HACK STRING EVAL +9.85290514677763 100 +8.754373501986265 100 +8.253532238304615 100 +5.07987292855978 100 +7.68168767541647 100 +11.119015634059906 100 +9.961699433624744 100 +7.737268328666687 100 +6.125767152756453 100 +6.888051837682724 100 +#HACK STRING EVAL +5.964920908212662 100 +8.002341330051422 8 +3.9983697906136513 100 +7.924282431602478 8 +10.707665339112282 100 +9.46940815448761 100 +7.202503181993961 100 +7.742464005947113 100 +9.72039133310318 100 +2.411286860704422 100 +#HACK STRING EVAL +6.418930381536484 100 +5.4794687032699585 100 +8.298161119222641 100 +0.7842550575733185 100 +8.066740840673447 100 +5.749489486217499 100 +4.208433300256729 100 +7.423029661178589 100 +7.600053399801254 100 +1.4351311922073364 100 +#HACK STRING EVAL +7.606840372085571 100 +3.0693407356739044 100 +9.379783868789673 100 +5.77476966381073 100 +10.719555616378784 100 +7.662207543849945 100 +10.06666749715805 100 +6.805041790008545 100 +1.7270309329032898 100 +5.7278889417648315 100 +#HACK STRING EVAL +4.7250075340271 100 +5.15682727098465 100 +8.420142620801926 100 +10.57402217388153 100 +12.276178061962128 100 +2.102152466773987 100 +12.378023326396942 100 +8.882013082504272 100 +8.21159353852272 100 +5.179926514625549 100 +#HACK STRING EVAL +5.939670026302338 100 +3.6126144528388977 100 +2.5451276898384094 100 +3.5894737243652344 100 +8.79322212934494 100 +7.05995500087738 100 +6.433741629123688 100 +10.920737326145172 100 +8.67082554101944 100 +9.116136968135834 100 +#HACK STRING EVAL +7.91293203830719 100 +8.142730176448822 100 +5.561332732439041 100 +1.573451280593872 100 +7.771728992462158 100 +5.26404070854187 100 +2.2338629364967346 100 +6.514202356338501 100 +5.2424134612083435 100 +4.850088030099869 100 +#HACK STRING EVAL +8.498678147792816 100 +3.055811583995819 100 +8.170933902263641 100 +7.675503730773926 100 +9.49761414527893 100 +12.64508581161499 100 +9.675297319889069 100 +6.667328417301178 100 +10.574685633182526 100 +5.4534178376197815 100 +#HACK STRING EVAL +8.880505681037903 100 +9.15143683552742 100 +11.159815967082977 100 +7.6430690586566925 100 +3.1082045435905457 100 +8.1701158285141 100 +8.84312516450882 100 +5.069009363651276 100 +3.18337219953537 100 +5.808607518672943 100 +#HACK STRING EVAL +4.729503035545349 100 +12.962029308080673 100 +9.90478864312172 100 +6.774927616119385 100 +10.846415996551514 100 +3.7810726165771484 100 +0.649043083190918 100 +5.4631242752075195 100 +11.482960999011993 100 +9.585568845272064 100 +#HACK STRING EVAL +5.985563933849335 100 +10.056873500347137 100 +10.620717912912369 100 +3.913257449865341 100 +11.81602668762207 100 +2.5849834084510803 100 +9.150628447532654 100 +5.326503396034241 100 +8.631384491920471 100 +8.34828245639801 100 +#HACK STRING EVAL +10.7849280834198 100 +9.664008110761642 100 +10.631111085414886 100 +5.027460336685181 100 +8.674555599689484 100 +9.021582126617432 100 +8.4235999584198 100 +10.234527468681335 100 +5.037157833576202 100 +7.659717261791229 100 +#HACK STRING EVAL +8.18967017531395 100 +2.7766048908233643 100 +11.45438665151596 100 +3.986038565635681 100 +7.917270928621292 100 +8.413396120071411 100 +8.64169591665268 100 +9.249706506729126 100 +7.523860335350037 100 +11.945570170879364 100 +#HACK STRING EVAL +3.823022782802582 100 +5.935826063156128 100 +11.018980741500854 100 +7.94812136888504 100 +4.95865136384964 100 +12.909743666648865 100 +0.229786217212677 100 +9.327658206224442 100 +1.1121402382850647 100 +7.189923405647278 100 +#HACK STRING EVAL +6.358874261379242 100 +4.069714695215225 100 +10.230975925922394 100 +7.894906044006348 100 +9.046864598989487 100 +6.871271133422852 100 +7.931209206581116 100 +9.040899217128754 100 +1.8842962086200714 100 +7.892801523208618 100 +#HACK STRING EVAL +4.872601628303528 100 +9.09286618232727 100 +8.973569929599762 100 +4.218550682067871 100 +9.255084544420242 100 +9.039937734603882 100 +8.709646582603455 100 +6.2475666999816895 100 +4.40944841504097 100 +9.50962221622467 100 +#HACK STRING EVAL +4.416699677705765 100 +7.412730574607849 100 +7.167260587215424 100 +10.713550984859467 100 +6.50444769859314 100 +7.874801576137543 100 +6.558664381504059 100 +8.472576200962067 100 +7.649648725986481 100 +3.696353852748871 100 +#HACK STRING EVAL +-3.7503671646118164 100 +-6.669588088989258 100 +-7.995953559875488 100 +-4.92095947265625 100 +-6.310798645019531 100 +-4.496591567993164 100 +-9.295823574066162 100 +-2.968735694885254 100 +-5.535251617431641 100 +-5.104723930358887 100 +#HACK STRING EVAL +6.132507264614105 100 +4.9933425188064575 100 +8.060433983802795 100 +10.37150353193283 100 +5.691354811191559 100 +9.889916718006134 100 +9.174466788768768 100 +8.67982429265976 100 +7.538052141666412 100 +9.321741968393326 100 +#HACK STRING EVAL +9.8448342718184 100 +8.746302552521229 100 +8.271458394825459 11 +5.071802079677582 100 +7.6736168302595615 100 +11.110944710671902 100 +9.953628443181515 100 +7.729197420179844 100 +6.1176963448524475 100 +6.914454162120819 9 +#HACK STRING EVAL +6.059924334287643 100 +7.771409310400486 100 +4.203561633825302 100 +7.6728405356407166 100 +10.779317244887352 100 +9.911652386188507 10 +7.2975065261125565 100 +7.837467432022095 100 +9.925583362579346 100 +2.6164789348840714 100 +#HACK STRING EVAL +6.534338980913162 100 +5.705513179302216 100 +8.39512713253498 100 +0.7293486595153809 100 +8.182149469852448 100 +5.743455678224564 100 +4.202399432659149 100 +7.649074375629425 100 +7.697019279003143 100 +1.5739027857780457 100 +#HACK STRING EVAL +7.4611316323280334 100 +3.1916152238845825 100 +9.502057671546936 100 +5.747364103794098 100 +10.647448360919952 100 +7.746391594409943 100 +10.192142933607101 100 +6.777636766433716 100 +1.8112145066261292 100 +5.812073051929474 100 +#HACK STRING EVAL +4.711811363697052 100 +5.297094106674194 100 +8.560409307479858 100 +10.641948461532593 100 +12.344105452299118 100 +2.0189898908138275 100 +12.445970296859741 100 +8.725232362747192 100 +8.351860672235489 100 +5.023145914077759 100 +#HACK STRING EVAL +5.989271402359009 100 +3.662951946258545 100 +2.594265937805176 100 +3.534373939037323 100 +8.706741333007812 100 +6.9841267466545105 100 +6.484071671962738 100 +10.78936904668808 100 +8.721162021160126 100 +9.061123996973038 100 +#HACK STRING EVAL +7.816248595714569 100 +8.049400687217712 100 +5.609258353710175 100 +1.480116844177246 100 +7.861252427101135 100 +5.353630363941193 100 +2.1440666913986206 100 +6.603750109672546 100 +5.331964880228043 100 +4.753458619117737 100 +#HACK STRING EVAL +8.451778829097748 100 +3.010823428630829 100 +8.120570242404938 100 +7.710207641124725 100 +9.453897535800934 100 +12.599104404449463 100 +9.710205733776093 100 +6.747347831726074 100 +10.654758155345917 100 +5.483610898256302 100 +#HACK STRING EVAL +8.979153394699097 100 +8.891929745674133 100 +11.255613446235657 100 +7.3859169483184814 100 +2.852858603000641 100 +8.269471108913422 100 +8.939586341381073 100 +5.008709967136383 100 +3.294791132211685 100 +6.040607511997223 100 +#HACK STRING EVAL +4.844011068344116 100 +12.758698493242264 100 +9.695314228534698 100 +6.925106227397919 100 +11.050485253334045 100 +3.9859774708747864 100 +0.800230860710144 100 +5.464473307132721 100 +11.340343356132507 100 +9.442732602357864 100 +#HACK STRING EVAL +5.883689373731613 100 +10.391438007354736 100 +10.732019305229187 100 +4.247365772724152 100 +11.453217208385468 100 +2.9186850786209106 100 +9.484340131282806 100 +5.0329344272613525 100 +8.651273369789124 100 +8.283251225948334 100 +#HACK STRING EVAL +10.488240897655487 100 +9.512974679470062 100 +10.793807923793793 100 +5.11335563659668 100 +8.567689657211304 100 +9.041816771030426 100 +8.437568426132202 100 +10.132606387138367 100 +5.21705037355423 100 +7.560698479413986 100 +#HACK STRING EVAL +8.13115805387497 100 +2.6226843297481537 100 +11.661324322223663 100 +4.231751084327698 100 +8.127799421548843 100 +8.255226165056229 100 +8.503130793571472 100 +9.47345519065857 100 +7.2227747440338135 100 +12.226889908313751 100 +#HACK STRING EVAL +3.923266291618347 100 +6.084172248840332 100 +11.084347069263458 100 +8.02060067653656 100 +4.929127931594849 100 +13.068755954504013 100 +0.13958114385604858 100 +9.421959817409515 100 +1.0568442344665527 100 +7.310394585132599 100 +#HACK STRING EVAL +6.2305737137794495 100 +3.6188079714775085 100 +10.363168209791183 100 +7.773860812187195 100 +8.829756736755371 100 +7.009815871715546 100 +7.824150383472443 100 +8.82958871126175 100 +2.341250330209732 100 +8.012221097946167 100 +#HACK STRING EVAL +4.55588299036026 100 +9.186736702919006 100 +9.211251556873322 100 +4.45904803276062 100 +9.156938821077347 100 +9.281045317649841 100 +8.853575468063354 100 +6.486712336540222 100 +4.506881475448608 100 +9.315610826015472 100 +#HACK STRING EVAL +4.296995639801025 100 +7.595842182636261 100 +7.2512664794921875 100 +10.891624689102173 100 +6.688275873661041 100 +8.034596502780914 100 +6.654384911060333 100 +8.296931743621826 100 +7.73858842253685 100 +3.5816662907600403 100 +#HACK STRING EVAL +-0.04198741912841797 100 +-6.669588088989258 100 +-7.995953559875488 100 +-4.92095947265625 100 +-6.310798645019531 100 +-4.496591567993164 100 +-9.295823574066162 100 +-2.968735694885254 100 +-1.8268718719482422 100 +-5.104723930358887 100 +#HACK STRING EVAL +6.3063719272613525 100 +5.166957587003708 100 +8.231922373175621 100 +10.54296612739563 100 +5.863703966140747 100 +10.063438653945923 100 +9.345929369330406 100 +8.85129664838314 100 +7.709591135382652 100 +9.49381372332573 100 +#HACK STRING EVAL +9.905021026730537 13 +8.812038019299507 11 +8.295608073472977 9 +5.110341511666775 8 +7.710492879152298 10 +11.143531989306211 12 +9.983048435300589 12 +7.765618450939655 10 +6.189442038536072 8 +6.945022001862526 9 +#HACK STRING EVAL +5.762856036424637 100 +7.4392227828502655 100 +3.8947267681360245 100 +7.364005506038666 100 +10.470482349395752 100 +9.365765035152435 100 +7.00043822824955 100 +7.540399074554443 100 +9.616748347878456 100 +2.3427620381116867 100 +#HACK STRING EVAL +6.505996584892273 100 +5.61769300699234 100 +8.307306945323944 100 +0.6154578328132629 100 +8.153807073831558 100 +5.68814817070961 100 +4.080872446298599 100 +7.56125408411026 100 +7.609199106693268 100 +1.522197425365448 100 +#HACK STRING EVAL +7.474083423614502 100 +3.137896180152893 100 +9.354216694831848 100 +5.816215932369232 100 +10.760967999696732 100 +7.598136126995087 100 +10.138423919677734 100 +6.745886027812958 100 +1.7046632170677185 100 +5.705513775348663 100 +#HACK STRING EVAL +4.635533928871155 100 +5.145631790161133 100 +8.483169674873352 100 +10.484191596508026 100 +12.266899228096008 100 +2.090808391571045 100 +12.368333667516708 100 +8.785711199045181 100 +8.273944437503815 100 +5.2403009831905365 100 +#HACK STRING EVAL +5.98954850435257 100 +3.696099579334259 100 +2.374412477016449 100 +3.5509603023529053 100 +8.708710789680481 100 +7.217122972011566 100 +6.738426566123962 100 +10.79902508854866 100 +8.727495312690735 100 +9.057752579450607 100 +#HACK STRING EVAL +7.807330310344696 100 +8.220601975917816 100 +5.7922027707099915 100 +1.6700654029846191 100 +7.863515257835388 100 +5.407271385192871 100 +2.3364517986774445 100 +6.602813124656677 100 +5.387218475341797 100 +4.7061731815338135 100 +#HACK STRING EVAL +8.444720894098282 100 +2.992225080728531 100 +8.358889818191528 100 +7.727108597755432 100 +9.44833818078041 100 +12.580765545368195 100 +9.737724304199219 100 +6.980597376823425 100 +10.888037383556366 100 +5.500177949666977 100 +#HACK STRING EVAL +8.94330495595932 100 +8.938669323921204 100 +11.219615876674652 100 +7.500307261943817 100 +2.871052861213684 100 +8.217535376548767 100 +8.899417966604233 100 +5.122951030731201 100 +3.234441876411438 100 +5.996186465024948 100 +#HACK STRING EVAL +4.795831143856049 100 +12.940799862146378 100 +9.875788301229477 100 +6.870733976364136 100 +10.872718513011932 100 +3.8018465638160706 100 +0.7390497922897339 100 +5.406926333904266 100 +11.426078021526337 100 +9.749904334545135 100 +#HACK STRING EVAL +6.1010631918907166 100 +10.256409585475922 100 +10.532971858978271 100 +4.1010589599609375 100 +11.605088710784912 100 +2.7688035666942596 100 +9.050987958908081 100 +5.192673861980438 100 +8.824047327041626 100 +8.450374960899353 100 +#HACK STRING EVAL +10.67428058385849 100 +9.714473217725754 100 +10.782073020935059 100 +5.225516200065613 100 +8.454581916332245 100 +8.854604721069336 100 +8.31433880329132 100 +10.145719587802887 100 +5.195720016956329 100 +7.538843631744385 100 +#HACK STRING EVAL +8.207730203866959 100 +2.5543596744537354 100 +11.726588994264603 100 +4.123752653598785 100 +7.841263473033905 100 +8.201438009738922 100 +8.444366753101349 100 +9.527458310127258 100 +7.153768062591553 100 +12.254574000835419 100 +#HACK STRING EVAL +3.7705012559890747 100 +6.33559250831604 100 +10.909447252750397 100 +7.877388954162598 100 +4.701278805732727 100 +12.897329092025757 100 +-0.10084941983222961 100 +9.169245481491089 100 +1.210215985774994 100 +7.114197731018066 100 +#HACK STRING EVAL +6.209583610296249 100 +3.725763201713562 100 +9.925613641738892 100 +7.7009397149086 100 +9.030660778284073 100 +7.095324099063873 100 +7.697964251041412 100 +9.025064259767532 100 +1.9005438089370728 100 +8.141503989696503 100 +#HACK STRING EVAL +4.873865783214569 100 +9.101837873458862 100 +9.47447657585144 100 +4.719105422496796 100 +9.438444793224335 100 +9.555514991283417 100 +9.1287901699543 100 +6.772602796554565 100 +4.23242050409317 100 +9.03772521018982 100 +#HACK STRING EVAL +3.975376605987549 100 +7.392725765705109 100 +6.747067302465439 100 +10.375287592411041 100 +6.1876198053359985 100 +7.52508607506752 100 +6.1021542847156525 100 +8.848863959312439 100 +7.222576677799225 100 +3.5958582758903503 100 +#HACK STRING EVAL +-0.9130115509033203 100 +-3.8811140060424805 100 +-4.116611480712891 100 +-1.1155481338500977 100 +-2.5079116821289062 100 +-0.69134521484375 100 +-5.487965106964111 100 +0.8270854949951172 100 +-2.641526222229004 100 +-1.3083181381225586 100 +#HACK STRING EVAL +6.373748138546944 100 +5.234333790838718 100 +8.299298584461212 100 +10.610342264175415 100 +5.931080102920532 100 +10.130814865231514 100 +9.413305550813675 100 +8.91867282986641 100 +7.776967287063599 100 +9.561189889907837 100 +#HACK STRING EVAL +9.568779051303864 100 +8.470247462391853 100 +8.275282353162766 13 +4.771492749452591 100 +7.373307466506958 100 +10.834889501333237 100 +9.653319165110588 100 +7.428888112306595 100 +5.817386895418167 100 +6.579671755433083 100 +#HACK STRING EVAL +5.8064800798892975 100 +7.51796492934227 100 +3.8159473538398743 100 +7.295598849654198 100 +10.497667521238327 100 +9.297358334064484 100 +6.992505192756653 100 +7.58402344584465 100 +9.537969052791595 100 +2.33482913300395 100 +#HACK STRING EVAL +6.377232193946838 100 +5.653050780296326 100 +8.314581334590912 100 +0.5779364705085754 100 +8.02504277229309 100 +5.765909552574158 100 +4.224853545427322 100 +7.568528741598129 100 +7.644556879997253 100 +1.3934330940246582 100 +#HACK STRING EVAL +7.711605459451675 100 +2.868971288204193 100 +9.179414331912994 100 +5.582518100738525 100 +10.916195183992386 100 +7.510527729988098 100 +9.869499862194061 100 +7.001685559749603 100 +1.9187599122524261 100 +5.576213598251343 100 +#HACK STRING EVAL +4.456880152225494 100 +4.842729210853577 100 +8.106044262647629 100 +10.305878520011902 100 +11.889740526676178 100 +2.281140983104706 100 +12.484679907560349 100 +9.170015513896942 100 +8.390571624040604 100 +4.865830779075623 100 +#HACK STRING EVAL +5.758196651935577 100 +3.9974588751792908 100 +2.363586723804474 100 +3.572514772415161 100 +8.412942290306091 100 +7.234835922718048 100 +6.819787830114365 100 +11.094751387834549 100 +9.048576563596725 100 +9.099455773830414 100 +#HACK STRING EVAL +8.19729769229889 100 +8.472087323665619 100 +5.835996687412262 100 +1.7076260149478912 100 +8.24237510561943 100 +5.734770357608795 100 +2.5667243599891663 100 +6.984896630048752 100 +5.71300533413887 100 +4.390949547290802 100 +#HACK STRING EVAL +8.638950049877167 100 +3.1985925436019897 100 +8.308283030986786 100 +7.539966493844986 100 +9.275674641132355 100 +12.787766218185425 100 +9.3220996260643 100 +7.162265956401825 100 +10.838808536529541 100 +5.313354134559631 100 +#HACK STRING EVAL +8.585314810276031 100 +8.651193082332611 100 +11.52455484867096 100 +7.385232448577881 100 +2.609576255083084 100 +8.121487379074097 100 +9.208477556705475 100 +4.766264885663986 100 +3.5401313304901123 100 +5.885975956916809 100 +#HACK STRING EVAL +4.6412506103515625 100 +12.505203664302826 100 +9.434869885444641 100 +6.713699460029602 100 +11.338078916072845 100 +4.2580984234809875 100 +0.5697892308235168 100 +5.570399850606918 100 +11.234157919883728 100 +9.6692413687706 100 +#HACK STRING EVAL +5.617969244718552 100 +10.06848132610321 100 +10.383239656686783 100 +4.286372393369675 100 +11.785091578960419 100 +2.5877997279167175 100 +9.557735294103622 100 +5.609107106924057 100 +8.385213315486908 100 +7.991509765386581 100 +#HACK STRING EVAL +10.784533977508545 100 +9.266362428665161 100 +10.645963668823242 100 +5.284292370080948 100 +8.71628475189209 100 +9.04368770122528 100 +8.42594039440155 100 +10.398783683776855 100 +5.086641013622284 100 +7.417009711265564 100 +#HACK STRING EVAL +8.339474856853485 100 +2.7741833925247192 100 +11.509624481201172 100 +4.492767930030823 100 +7.9753376841545105 100 +8.414291858673096 100 +8.923150926828384 100 +9.310802578926086 100 +7.375523269176483 100 +11.784121632575989 100 +#HACK STRING EVAL +3.6951560974121094 100 +5.89224499464035 100 +11.216109037399292 100 +8.107582777738571 100 +5.215686768293381 100 +12.857639014720917 100 +0.34702664613723755 100 +9.336599051952362 100 +0.9099689722061157 100 +7.105310916900635 100 +#HACK STRING EVAL +5.9018940925598145 100 +3.8314141631126404 100 +10.413228988647461 100 +7.473752677440643 100 +8.758986502885818 100 +7.298500597476959 100 +7.85396546125412 100 +8.449219048023224 100 +2.510040521621704 100 +7.9817622900009155 100 +#HACK STRING EVAL +4.351040363311768 100 +9.64311945438385 100 +9.178297698497772 100 +4.419299602508545 100 +8.717980831861496 100 +9.243553698062897 100 +8.821882426738739 100 +6.447340965270996 100 +4.534220188856125 100 +9.338194847106934 100 +#HACK STRING EVAL +4.326208591461182 100 +7.536651134490967 100 +7.155602872371674 100 +10.853329688310623 100 +6.8289307951927185 100 +8.111611068248749 100 +6.495118618011475 100 +8.177759766578674 100 +7.805956721305847 100 +3.428382456302643 100 +#HACK STRING EVAL +-3.7503671646118164 100 +-2.9631223678588867 100 +-7.995953559875488 100 +-4.92095947265625 100 +-6.310798645019531 100 +-4.496591567993164 100 +-9.295823574066162 100 +-2.968735694885254 100 +-5.535251617431641 100 +-5.104723930358887 100 +#HACK STRING EVAL +6.455647133290768 100 +5.316232822835445 100 +8.439225271344185 12 +10.692241333425045 100 +6.012979172170162 100 +10.212713815271854 100 +9.546113923192024 13 +9.055943913757801 13 +7.858866356313229 100 +9.643088959157467 100 +#HACK STRING EVAL +9.78676538169384 100 +8.688233718276024 100 +8.18739241361618 100 +5.013733088970184 100 +7.615547940135002 100 +11.052875846624374 100 +9.895559594035149 100 +7.671128585934639 100 +6.05962735414505 100 +6.82191202044487 100 +#HACK STRING EVAL +5.985856756567955 100 +7.697341755032539 100 +4.152845561504364 100 +7.367878153920174 100 +10.474355161190033 100 +9.369637936353683 100 +7.223438933491707 100 +7.763399809598923 100 +9.620621055364609 100 +2.3115166276693344 100 +#HACK STRING EVAL +6.527099132537842 100 +5.620125651359558 100 +8.309739530086517 100 +0.722108781337738 100 +8.174909621477127 100 +5.728579491376877 100 +4.18752333521843 100 +7.5636867582798 100 +7.611631833016872 100 +1.5757882595062256 100 +#HACK STRING EVAL +7.594061553478241 100 +3.0544411540031433 100 +9.39823704957962 100 +5.8350746631622314 100 +10.78037816286087 100 +7.683862566947937 100 +10.088322505354881 100 +6.865346670150757 100 +1.7829382717609406 100 +5.783796072006226 100 +#HACK STRING EVAL +4.722205638885498 100 +5.098204612731934 100 +8.489664912223816 100 +10.443058907985687 100 +12.14521598815918 100 +2.0268080830574036 100 +12.247080683708191 100 +8.926933407783508 100 +8.84055870771408 8 +5.104583919048309 100 +#HACK STRING EVAL +5.786757469177246 100 +3.648851603269577 100 +2.6500927209854126 100 +3.2877054810523987 100 +8.762243092060089 100 +6.96265172958374 100 +6.469919800758362 100 +11.020812094211578 100 +8.972966492176056 100 +8.827261447906494 100 +#HACK STRING EVAL +8.06373217701912 100 +7.993705332279205 100 +5.5537338852882385 100 +1.424434244632721 100 +8.102109014987946 100 +5.601130098104477 100 +2.088394522666931 100 +6.844620853662491 100 +5.234671771526337 100 +4.527337074279785 100 +#HACK STRING EVAL +8.355399668216705 100 +2.9145296812057495 100 +8.024003863334656 100 +7.8165179789066315 100 +9.357442140579224 100 +12.502575635910034 100 +9.816466361284256 100 +7.104134649038315 100 +11.01151728630066 100 +5.173077166080475 100 +#HACK STRING EVAL +9.187118381261826 100 +8.71373987197876 100 +11.4637171626091 100 +7.744661629199982 100 +2.674317181110382 100 +8.477298974990845 100 +9.147519052028656 100 +4.8303132355213165 100 +2.9134520888328552 100 +6.255198240280151 100 +#HACK STRING EVAL +4.473726391792297 100 +12.982705056667328 100 +9.918752670288086 100 +7.0374926924705505 100 +11.322050422430038 100 +3.7462413907051086 100 +0.9124990701675415 100 +5.224505543708801 100 +11.242109030485153 100 +9.347436606884003 100 +#HACK STRING EVAL +5.615635454654694 100 +10.435337543487549 100 +10.3737753033638 100 +4.289728105068207 100 +11.412104487419128 100 +2.9629705250263214 100 +9.538891345262527 100 +5.634979158639908 100 +9.008982181549072 100 +8.642489492893219 100 +#HACK STRING EVAL +10.992546796798706 100 +9.17235442996025 100 +11.082612603902817 100 +4.836923539638519 100 +8.298345923423767 100 +9.379826068878174 100 +8.01220816373825 100 +9.860195875167847 100 +5.504432320594788 100 +7.841501593589783 100 +#HACK STRING EVAL +7.68010675907135 100 +2.4227046370506287 100 +11.780261784791946 100 +4.397473633289337 100 +7.677259981632233 100 +8.620113462209702 100 +8.87342882156372 100 +9.129431247711182 100 +7.022252678871155 100 +12.349349826574326 100 +#HACK STRING EVAL +4.20435506105423 100 +6.421966642141342 100 +11.346588164567947 100 +8.308958292007446 100 +4.603193283081055 100 +13.414351522922516 100 +-0.18365949392318726 100 +9.15994679927826 100 +0.778570830821991 100 +7.646859049797058 100 +#HACK STRING EVAL +6.550404965877533 100 +3.5880460143089294 100 +9.86193960905075 100 +7.524099260568619 100 +8.574918866157532 100 +7.273395419120789 100 +7.5739516615867615 100 +9.097370624542236 100 +2.3670495450496674 100 +8.277295529842377 100 +#HACK STRING EVAL +4.478053331375122 100 +8.905817747116089 100 +9.489532709121704 100 +4.743606388568878 100 +8.84222474694252 100 +9.560487300157547 100 +9.142014175653458 100 +6.764777719974518 100 +4.8255932331085205 100 +9.042028248310089 100 +#HACK STRING EVAL +3.9849286675453186 100 +7.91730397939682 100 +6.672205358743668 100 +10.894353985786438 100 +6.761106312274933 100 +8.053189277648926 100 +6.657370388507843 100 +8.891634196043015 100 +7.1340236365795135 100 +3.572849005460739 100 +#HACK STRING EVAL +-2.95572566986084 100 +-2.528461456298828 100 +-7.205278396606445 100 +-4.132027626037598 100 +-2.169672966003418 100 +-3.707996368408203 100 +-8.504710674285889 100 +1.1723909378051758 100 +-4.742600440979004 100 +-0.963597297668457 100 +#HACK STRING EVAL +6.458870060741901 100 +5.319455750286579 100 +8.445284932851791 11 +10.69546427577734 100 +6.016202099621296 100 +10.215936787426472 100 +9.498427517712116 100 +9.059017181396484 12 +7.862089283764362 100 +9.646311901509762 100 +#HACK STRING EVAL +9.748050764203072 100 +8.649518981575966 100 +8.148677662014961 100 +4.975018382072449 100 +7.576833114027977 100 +11.014161124825478 100 +9.856844753026962 100 +7.632413730025291 100 +6.020912542939186 100 +6.783197328448296 100 +#HACK STRING EVAL +5.72718358039856 100 +7.5812584310770035 100 +4.469274289906025 5 +7.9151758551597595 8 +10.545255921781063 100 +9.36521090567112 100 +7.009345173835754 100 +7.5047267228364944 100 +9.75878381729126 100 +2.889543890953064 3 +#HACK STRING EVAL +6.530924573540688 100 +5.511055409908295 100 +8.387099519371986 100 +0.7259344160556793 100 +8.2847580909729 100 +5.549757033586502 100 +4.0087010860443115 100 +7.352376222610474 100 +7.6889917850494385 100 +1.6531484127044678 100 +#HACK STRING EVAL +7.394524693489075 100 +3.2104591727256775 100 +9.52089387178421 100 +5.636052817106247 100 +10.679917842149734 100 +7.717452347278595 100 +10.12191390991211 100 +6.765408456325531 100 +1.5834035873413086 100 +5.584261655807495 100 +#HACK STRING EVAL +4.790762394666672 100 +5.294990003108978 100 +8.55815064907074 100 +10.639603286981583 100 +12.341653108596802 100 +1.9336730241775513 100 +12.137220233678818 100 +8.713532030582428 100 +8.349692225456238 100 +5.310937702655792 100 +#HACK STRING EVAL +6.048583418130875 100 +3.6356592774391174 100 +2.6536494195461273 100 +3.5694185197353363 100 +8.794914364814758 100 +6.9093849658966064 100 +6.4542030692100525 100 +10.73560118675232 100 +9.010490268468857 100 +9.08803516626358 100 +#HACK STRING EVAL +8.073055893182755 100 +7.961275339126587 100 +5.515385687351227 100 +1.391946703195572 100 +7.723991870880127 100 +5.218786180019379 100 +2.0505152344703674 100 +6.860585808753967 100 +5.2011925876140594 100 +4.893143504858017 100 +#HACK STRING EVAL +8.693273961544037 100 +2.859007239341736 100 +8.075293123722076 100 +7.468739420175552 100 +9.823532342910767 100 +12.554563105106354 100 +9.345431089401245 100 +7.114372134208679 100 +10.609537720680237 100 +5.64014858007431 100 +#HACK STRING EVAL +9.112874776124954 100 +9.2279412150383 100 +11.389483392238617 100 +7.670413762331009 100 +3.1900774240493774 100 +8.403198391199112 100 +9.073298662900925 100 +5.3384756445884705 100 +3.451631784439087 100 +5.7149346470832825 100 +#HACK STRING EVAL +4.990689337253571 100 +12.474192410707474 100 +9.944387197494507 100 +7.072127282619476 100 +10.782989531755447 100 +3.7370277047157288 100 +0.9481033682823181 100 +5.217095911502838 100 +11.196379005908966 100 +9.301615953445435 100 +#HACK STRING EVAL +6.251967370510101 100 +10.443938612937927 100 +11.009848594665527 100 +4.1598060131073 100 +11.417333662509918 100 +2.8314437866210938 100 +8.894012957811356 100 +5.5036483108997345 100 +9.01879796385765 100 +8.649730443954468 100 +#HACK STRING EVAL +10.538162678480148 100 +9.547325253486633 100 +10.859877675771713 100 +5.012194037437439 100 +8.473672151565552 100 +9.242342382669449 100 +8.187431931495667 100 +10.035411477088928 100 +5.281659513711929 100 +7.545791923999786 100 +#HACK STRING EVAL +8.115087807178497 100 +2.5965263843536377 100 +11.645715057849884 100 +3.7829668819904327 100 +8.113956868648529 100 +8.22283399105072 100 +8.256681770086288 100 +9.455797612667084 100 +7.191693902015686 100 +11.75051674246788 100 +#HACK STRING EVAL +3.671867549419403 100 +5.933666855096817 100 +10.84788191318512 100 +7.749745547771454 100 +5.069517135620117 100 +12.924422025680542 100 +0.2821699380874634 100 +9.337882727384567 100 +1.2570642232894897 100 +7.157695949077606 100 +#HACK STRING EVAL +6.3781644105911255 100 +4.041321963071823 100 +9.953361332416534 100 +7.924602031707764 100 +8.868053197860718 100 +6.827959775924683 100 +7.751127183437347 100 +8.949290812015533 100 +1.9984863996505737 100 +8.046947062015533 100 +#HACK STRING EVAL +5.1671059131622314 100 +8.827990412712097 100 +9.258859694004059 100 +4.828079104423523 100 +9.198521316051483 100 +9.324064522981644 100 +8.899485051631927 100 +6.533660054206848 100 +4.413299143314362 100 +9.221013963222504 100 +#HACK STRING EVAL +4.137681305408478 100 +7.70865136384964 100 +6.874803215265274 100 +10.507956445217133 100 +6.380454510450363 100 +7.846795916557312 100 +6.468592166900635 100 +8.628434181213379 100 +7.488117456436157 100 +3.697631597518921 100 +#HACK STRING EVAL +-3.7503671646118164 100 +-6.669588088989258 100 +-7.995953559875488 100 +-4.92095947265625 100 +-6.310798645019531 100 +-4.496591567993164 100 +-9.295823574066162 100 +-2.968735694885254 100 +-5.535251617431641 100 +-5.104723930358887 100 +#HACK STRING EVAL +6.510922368615866 20 +5.370938111096621 18 +8.42638973146677 13 +10.74271298572421 16 +6.060645759105682 12 +10.271793812513351 19 +9.541456412523985 14 +9.055806051939726 14 +7.918809313327074 15 +9.693344578146935 16 +#HACK STRING EVAL +9.820936374366283 100 +8.722404673695564 100 +8.22156347334385 100 +5.0479042530059814 100 +7.6497189700603485 100 +11.087046831846237 100 +9.929730579257011 100 +7.7549353539943695 9 +6.093798391520977 100 +6.8560830950737 100 +#HACK STRING EVAL +5.765878081321716 100 +7.418649688363075 100 +3.8741536140441895 100 +7.402145743370056 100 +10.449909180402756 100 +9.403905257582664 100 +7.0034602880477905 100 +7.484707832336426 100 +9.65488851070404 100 +2.345784083008766 100 +#HACK STRING EVAL +6.562325716018677 100 +5.622864007949829 100 +8.123230636119843 100 +0.568088173866272 100 +8.020888954401016 100 +5.574558913707733 100 +4.033502757549286 100 +7.566425025463104 100 +7.614370107650757 100 +1.5785264372825623 100 +#HACK STRING EVAL +7.532795786857605 100 +3.170456647872925 100 +9.253122448921204 100 +5.656225144863129 100 +10.719112038612366 100 +7.766524910926819 100 +9.94320797920227 100 +6.8045982122421265 100 +1.8313483595848083 100 +5.722530245780945 100 +#HACK STRING EVAL +4.480294585227966 100 +5.259292364120483 100 +8.247754573822021 100 +10.329294502735138 100 +12.031449615955353 100 +2.2046175599098206 100 +12.408169746398926 100 +8.984479069709778 100 +8.257119745016098 100 +5.780944347381592 6 +#HACK STRING EVAL +5.953921973705292 100 +3.757644832134247 100 +2.3616771697998047 100 +3.5243390798568726 100 +8.473778009414673 100 +7.186478555202484 100 +6.70660787820816 100 +10.737209349870682 100 +8.815859019756317 100 +9.051088780164719 100 +#HACK STRING EVAL +7.710173428058624 100 +8.297054052352905 100 +5.705813229084015 100 +1.7277125418186188 100 +7.916316747665405 100 +5.408569097518921 100 +2.391684517264366 100 +6.497680842876434 100 +5.38675332069397 100 +4.710410177707672 100 +#HACK STRING EVAL +8.68297415971756 100 +3.2420100569725037 100 +8.351689755916595 100 +7.586890637874603 100 +9.685035616159439 100 +12.830333948135376 100 +9.587320983409882 100 +6.834069758653641 100 +10.74114814400673 100 +5.410084247589111 100 +#HACK STRING EVAL +8.730202853679657 100 +8.97591120004654 100 +11.181949436664581 100 +7.468500912189484 100 +2.936729609966278 100 +8.023059904575348 100 +8.689758062362671 100 +4.909918248653412 100 +3.0201844573020935 100 +5.96740198135376 100 +#HACK STRING EVAL +4.570045351982117 100 +12.754068851470947 100 +9.68945574760437 100 +6.647709846496582 100 +11.037386268377304 100 +3.9732718467712402 100 +0.5203340649604797 100 +5.571341007947922 100 +11.58731734752655 100 +9.692309081554413 100 +#HACK STRING EVAL +5.95665717124939 100 +9.960752427577972 100 +10.715519368648529 100 +3.938000440597534 100 +11.883917093276978 100 +2.4883283972740173 100 +9.35817700624466 100 +5.465452879667282 100 +8.725782215595245 100 +8.35618132352829 100 +#HACK STRING EVAL +10.617160320281982 100 +9.497470796108246 100 +10.640818238258362 100 +5.237782299518585 100 +8.682444453239441 100 +9.093659698963165 100 +8.42514181137085 100 +10.244201600551605 100 +5.073693335056305 100 +7.413245141506195 100 +#HACK STRING EVAL +7.954838991165161 100 +2.9812541902065277 100 +11.600209057331085 100 +4.104615569114685 100 +7.7744616866111755 100 +8.330059349536896 100 +8.579421281814575 100 +9.10279405117035 100 +7.581937700510025 100 +12.068707585334778 100 +#HACK STRING EVAL +4.033954620361328 100 +5.865945518016815 100 +11.16565066576004 100 +8.131273806095123 100 +5.163816004991531 100 +12.871333628892899 100 +0.36788150668144226 100 +9.326935291290283 100 +0.942342221736908 100 +7.371707618236542 100 +#HACK STRING EVAL +6.046743392944336 100 +3.622986853122711 100 +10.337168782949448 100 +7.952224850654602 100 +8.613766014575958 100 +6.8548941016197205 100 +8.032213360071182 100 +8.672725081443787 100 +2.3310343623161316 100 +7.856890916824341 100 +#HACK STRING EVAL +4.60213577747345 100 +9.394986659288406 100 +8.9889417886734 100 +4.230675965547562 100 +9.001156240701675 100 +9.055513858795166 100 +8.633586168289185 100 +6.681715607643127 100 +4.389613151550293 100 +9.548310458660126 100 +#HACK STRING EVAL +4.037269592285156 100 +7.313931703567505 100 +7.1278321743011475 100 +10.76699310541153 100 +6.667233377695084 100 +7.882254093885422 100 +6.7265161871910095 100 +8.231384694576263 100 +7.601985216140747 100 +4.185733586549759 100 +#HACK STRING EVAL +-3.7503671646118164 100 +7.422881830483675 45 +-7.995953559875488 100 +-4.92095947265625 100 +7.784607358276844 51 +-4.496591567993164 100 +-9.295823574066162 100 +11.12387277930975 58 +-5.535251617431641 100 +8.989943280816078 56 +#HACK STRING EVAL +6.452602177858353 100 +5.31318786740303 100 +8.378152683377266 100 +10.689196422696114 100 +6.009934216737747 100 +10.209668949246407 100 +9.492159679532051 100 +8.997526928782463 100 +7.855821415781975 100 +9.640044055879116 100 +#HACK STRING EVAL +9.783304512500763 100 +8.646710559725761 100 +8.036593571305275 100 +4.910510286688805 100 +7.539111882448196 100 +10.986643671989441 100 +9.83812502026558 100 +7.756631851196289 11 +5.981992423534393 100 +6.7448746263980865 100 +#HACK STRING EVAL +5.678908050060272 100 +7.4297886192798615 100 +3.885292634367943 100 +7.930633783340454 8 +10.562457263469696 100 +9.316935241222382 100 +6.916490197181702 100 +7.456451177597046 100 +9.597927749156952 100 +2.288823038339615 100 +#HACK STRING EVAL +6.437743902206421 100 +5.493952929973602 100 +8.187896221876144 100 +0.685484379529953 100 +8.13828393816948 100 +5.749406456947327 100 +4.208350300788879 100 +7.4375123381614685 100 +7.48545777797699 100 +1.4539448618888855 100 +#HACK STRING EVAL +7.668005526065826 100 +2.9721587896347046 100 +9.525111675262451 100 +5.909535884857178 100 +10.854321956634521 100 +7.810802161693573 100 +10.21473777294159 100 +6.651155471801758 100 +1.8756358325481415 100 +5.8759050369262695 100 +#HACK STRING EVAL +4.768801420927048 100 +5.017511785030365 100 +8.280827105045319 100 +10.624549984931946 100 +12.064523696899414 100 +1.9504602551460266 100 +12.42264848947525 100 +8.731730043888092 100 +8.05871069431305 100 +5.023175239562988 100 +#HACK STRING EVAL +5.726140737533569 100 +3.9808509349823 100 +2.669064462184906 100 +3.2520604133605957 100 +8.782706081867218 100 +6.9205076694488525 100 +6.438142001628876 100 +11.049730360507965 100 +9.013037890195847 100 +8.76664251089096 100 +#HACK STRING EVAL +8.067398488521576 100 +7.957011520862579 100 +5.902080714702606 100 +1.3975541591644287 100 +8.138348281383514 100 +5.604790210723877 100 +2.048867166042328 100 +6.854934900999069 100 +5.210775673389435 100 +4.522542476654053 100 +#HACK STRING EVAL +8.337363839149475 100 +2.920884370803833 100 +8.038182556629181 100 +7.821840792894363 100 +9.359788298606873 100 +12.51613575220108 100 +9.400797992944717 100 +7.105618476867676 100 +11.013002544641495 100 +5.594472587108612 100 +#HACK STRING EVAL +9.00128322839737 100 +8.73395299911499 100 +11.258964598178864 100 +7.552403628826141 100 +2.694542407989502 100 +8.29271924495697 100 +8.957874119281769 100 +4.850530207157135 100 +3.3045727908611298 100 +5.73152756690979 100 +#HACK STRING EVAL +4.9407884776592255 100 +12.602624863386154 100 +9.448949962854385 100 +6.984914630651474 100 +11.299534142017365 100 +4.234458297491074 100 +0.856491893529892 100 +5.302357852458954 100 +11.307623505592346 100 +9.384511977434158 100 +#HACK STRING EVAL +5.76970249414444 100 +10.2763671875 100 +10.526108086109161 100 +4.122196972370148 100 +11.579042673110962 100 +2.7957813441753387 100 +9.382276028394699 100 +5.490805506706238 100 +8.550534546375275 100 +8.469934850931168 100 +#HACK STRING EVAL +10.705030858516693 100 +9.217849850654602 100 +10.795731782913208 100 +5.158893167972565 100 +8.951248496770859 100 +9.173709690570831 100 +8.302382111549377 100 +10.159914046525955 100 +5.218169331550598 100 +7.530685007572174 100 +#HACK STRING EVAL +8.063888907432556 100 +2.8972702622413635 100 +11.487711429595947 100 +4.20729786157608 100 +8.037255883216858 100 +8.530311822891235 100 +8.778830885887146 100 +9.206607580184937 100 +7.500972211360931 100 +12.154357850551605 100 +#HACK STRING EVAL +3.8381174206733704 100 +5.978031516075134 100 +11.16314285993576 100 +8.102091252803802 100 +5.057340502738953 100 +12.952810764312744 100 +0.2573145031929016 100 +9.3744997382164 100 +0.9922170042991638 100 +7.188884913921356 100 +#HACK STRING EVAL +6.285804957151413 100 +3.8330507278442383 100 +10.10190999507904 100 +7.801682651042938 100 +8.866153717041016 100 +6.981460928916931 100 +7.830377399921417 100 +8.807788252830505 100 +2.1333011090755463 100 +8.005598306655884 100 +#HACK STRING EVAL +4.689879596233368 100 +9.30477648973465 100 +9.344536781311035 100 +4.587699770927429 100 +9.041591346263885 100 +9.414015650749207 100 +8.990806937217712 100 +6.618741810321808 100 +4.447496473789215 100 +9.173483788967133 100 +#HACK STRING EVAL +4.249020934104919 100 +7.642489671707153 100 +7.00321301817894 100 +10.64998859167099 100 +6.38933801651001 100 +7.726338326931 100 +6.424018323421478 100 +8.536280035972595 100 +7.4885894656181335 100 +3.8197622895240784 100 +#HACK STRING EVAL +-3.7503671646118164 100 +1.4200448989868164 100 +5.386215448379517 100 +5.953625679016113 100 +4.276979684829712 100 +6.149091005325317 100 +3.2639881372451782 100 +5.07230806350708 100 +-5.535251617431641 100 +4.122786045074463 100 +#HACK STRING EVAL +5.935803294181824 100 +4.7963889837265015 100 +7.861353576183319 100 +10.172397494316101 100 +5.493135333061218 100 +9.69286996126175 100 +8.97536051273346 100 +8.480727910995483 100 +7.33902245759964 100 +9.123245120048523 100 +#HACK STRING EVAL +9.804380789399147 100 +8.705848902463913 100 +8.20500798523426 100 +5.031348712742329 100 +7.633163444697857 100 +11.070491328835487 100 +9.913175098598003 100 +7.6887440755963326 100 +6.077242866158485 100 +6.839527472853661 100 +#HACK STRING EVAL +5.905435711145401 100 +7.608743876218796 100 +4.064247936010361 100 +7.533526793122292 100 +10.648180186748505 100 +9.543463051319122 100 +7.143017932772636 100 +7.682978630065918 100 +9.786269500851631 100 +2.8617085814476013 3 +#HACK STRING EVAL +6.5036106407642365 100 +5.591854155063629 100 +8.267925888299942 100 +0.7127834558486938 100 +8.1514210999012 100 +5.749918580055237 100 +4.208862483501434 100 +7.5077099204063416 100 +7.6004825830459595 100 +1.5198115110397339 100 +#HACK STRING EVAL +7.602591276168823 100 +3.029701590538025 100 +9.322868287563324 100 +6.4234819412231445 6 +10.78890746831894 100 +7.608493775129318 100 +10.030229687690735 100 +6.874393403530121 100 +1.7914672493934631 100 +5.674175202846527 100 +#HACK STRING EVAL +4.4881739020347595 100 +5.225571572780609 100 +8.488883674144745 100 +10.337171971797943 100 +12.272580713033676 100 +2.2389962673187256 100 +12.218519568443298 100 +8.794829815626144 100 +8.280336558818817 100 +5.092738062143326 100 +#HACK STRING EVAL +5.994743853807449 100 +3.698907256126404 100 +2.33906090259552 100 +3.5084773302078247 100 +8.712232053279877 100 +7.227540493011475 100 +6.5200225710868835 100 +10.804944962263107 100 +8.75714111328125 100 +9.092144250869751 100 +#HACK STRING EVAL +7.699723601341248 100 +8.301890432834625 100 +5.861948490142822 100 +1.732636034488678 100 +7.744812428951263 100 +5.413230538368225 100 +2.245142489671707 100 +6.487296164035797 100 +5.391485095024109 100 +4.706297934055328 100 +#HACK STRING EVAL +8.730434387922287 100 +3.2901986241340637 100 +8.400217413902283 100 +7.669090270996094 100 +9.625150620937347 100 +12.877898752689362 100 +9.395735502243042 100 +6.823318123817444 100 +10.930695712566376 100 +5.1694168746471405 100 +#HACK STRING EVAL +8.664270639419556 100 +9.038021385669708 100 +10.941679656505585 100 +7.222609460353851 100 +2.9996854662895203 100 +7.952319532632828 100 +8.624803632497787 100 +4.843558490276337 100 +2.9565832018852234 100 +5.9162203669548035 100 +#HACK STRING EVAL +4.633364796638489 100 +12.810385286808014 100 +9.708160638809204 100 +6.713276028633118 100 +11.035463750362396 100 +3.9698557257652283 100 +0.5865305364131927 100 +5.514985382556915 100 +11.531447291374207 100 +9.634903371334076 100 +#HACK STRING EVAL +5.942131578922272 100 +9.821641862392426 100 +10.700216114521027 100 +3.6768307089805603 100 +12.015911161899567 100 +2.3486539721488953 100 +9.206216871738434 100 +5.020667552947998 100 +8.395341008901596 100 +8.344714641571045 100 +#HACK STRING EVAL +11.214111626148224 9 +9.449507355690002 100 +10.395644098520279 100 +5.471476435661316 100 +8.929865509271622 100 +8.77854898571968 100 +8.64403909444809 100 +10.491474032402039 100 +4.816853106021881 100 +7.423030614852905 100 +#HACK STRING EVAL +8.057711631059647 100 +3.059198647737503 100 +11.203604310750961 100 +4.204975068569183 100 +7.6717435121536255 100 +8.685585916042328 100 +8.936854481697083 100 +9.015241146087646 100 +7.655086159706116 100 +12.15611344575882 100 +#HACK STRING EVAL +3.8260629177093506 100 +5.675516575574875 100 +10.9871706366539 100 +7.9383692145347595 100 +5.3231978714466095 100 +12.666760623455048 100 +0.536919355392456 100 +9.081351518630981 100 +1.1411070823669434 100 +7.176794469356537 100 +#HACK STRING EVAL +6.364572048187256 100 +3.9269551038742065 100 +10.053014814853668 100 +8.14174097776413 100 +8.464340299367905 100 +6.637551009654999 100 +8.175763607025146 100 +8.906551867723465 100 +2.0239457488059998 100 +7.637533605098724 100 +#HACK STRING EVAL +5.053480267524719 100 +9.63778018951416 100 +8.77171540260315 100 +4.017164081335068 100 +8.71094873547554 100 +8.837952256202698 100 +8.550332367420197 100 +6.04553559422493 100 +4.958886802196503 100 +9.610887318849564 100 +#HACK STRING EVAL +4.541192710399628 100 +7.714586615562439 100 +7.288164138793945 100 +10.705315828323364 100 +6.513932108879089 100 +7.878938019275665 100 +6.674856722354889 100 +8.497962892055511 100 +7.5586389899253845 100 +4.1311845779418945 100 +#HACK STRING EVAL +-3.7503671646118164 100 +-6.669588088989258 100 +-7.995953559875488 100 +-2.01517391204834 100 +-3.405013084411621 100 +-1.590806007385254 100 +-6.390038013458252 100 +-0.06295013427734375 100 +-5.535251617431641 100 +-2.1989383697509766 100 +#HACK STRING EVAL +4.264625549316406 100 +3.1260008811950684 100 +6.199145555496216 100 +8.508577585220337 100 +3.8267204761505127 100 +8.01834225654602 100 +7.3137030601501465 100 +6.818854093551636 100 +5.677546486258507 100 +7.455122709274292 100 +#HACK STRING EVAL +9.601066499948502 100 +8.502534747123718 100 +8.00169363617897 100 +4.828034281730652 100 +7.429849028587341 100 +10.86717689037323 100 +9.70986071228981 100 +7.485429674386978 100 +5.87392845749855 100 +6.6362132132053375 100 +#HACK STRING EVAL +6.2502705454826355 7 +7.957060724496841 9 +4.408592969179153 5 +7.891107812523842 11 +10.989859029650688 12 +9.90109658241272 9 +7.484782636165619 8 +8.067058622837067 9 +10.107648804783821 14 +2.8238941431045532 4 +#HACK STRING EVAL +6.61213618516922 100 +5.591024935245514 100 +8.280638754367828 100 +0.8071455284953117 100 +8.259946525096893 100 +5.8136164247989655 100 +4.272560298442841 100 +7.534585863351822 100 +8.12585985660553 7 +1.5466874837875366 100 +#HACK STRING EVAL +7.656943827867508 100 +3.043108969926834 100 +9.3535515666008 100 +5.756655305624008 100 +10.843260496854782 100 +7.780996948480606 100 +10.043637812137604 100 +6.928746998310089 100 +1.8458202481269836 100 +5.8466790318489075 100 +#HACK STRING EVAL +4.806615650653839 100 +5.061401546001434 100 +8.328738689422607 100 +10.41036632657051 100 +12.112502336502075 100 +2.0067266821861267 100 +12.21439129114151 100 +8.990611910820007 100 +8.116168200969696 100 +5.749426960945129 6 +#HACK STRING EVAL +5.786514580249786 100 +3.770995169878006 100 +2.5629957914352417 100 +3.4098469614982605 100 +8.675096213817596 100 +6.962461709976196 100 +6.744681179523468 100 +10.938527703285217 100 +8.981657445430756 100 +8.827076107263565 100 +#HACK STRING EVAL +8.069623976945877 100 +8.185116589069366 100 +5.745113968849182 100 +1.6157886385917664 100 +8.114682018756866 100 +5.607362151145935 100 +2.2798130810260773 100 +6.683758556842804 100 +5.426030546426773 100 +4.505648910999298 100 +#HACK STRING EVAL +8.34958240389824 100 +3.1229948103427887 100 +8.232469737529755 100 +7.612811923027039 100 +9.565921902656555 100 +12.711041033267975 100 +9.612743318080902 100 +7.0702850222587585 100 +10.764141738414764 100 +5.16846227645874 100 +#HACK STRING EVAL +8.694705843925476 100 +8.758674919605255 100 +11.397811979055405 100 +7.252284228801727 100 +2.7191891074180603 100 +8.129680514335632 100 +8.799779236316681 100 +4.875216126441956 100 +2.9868322014808655 100 +6.1826296746730804 100 +#HACK STRING EVAL +4.696587800979614 100 +12.594341278076172 100 +9.530745804309845 100 +6.778018772602081 100 +11.062877535820007 100 +4.11933034658432 100 +0.6539837718009949 100 +5.475957006216049 100 +11.316300630569458 100 +9.60052216053009 100 +#HACK STRING EVAL +5.855246901512146 100 +10.049883782863617 100 +10.52051454782486 100 +3.9064135551452637 100 +11.791254669427872 100 +2.5780556201934814 100 +9.351195931434631 100 +5.457829833030701 100 +8.624498307704926 100 +8.257759869098663 100 +#HACK STRING EVAL +10.716301620006561 100 +9.42998468875885 100 +10.713889002799988 100 +5.808523654937744 6 +8.642463505268097 100 +9.096336275339127 100 +8.356709122657776 100 +10.204185724258423 100 +5.135411858558655 100 +7.292678117752075 100 +#HACK STRING EVAL +8.054456740617752 100 +2.679317593574524 100 +11.408053398132324 100 +4.244493842124939 100 +8.095615446567535 100 +8.467000246047974 100 +8.720266699790955 100 +9.39557659626007 100 +7.273633241653442 100 +12.156202673912048 100 +#HACK STRING EVAL +4.094507575035095 100 +6.1720141768455505 100 +11.240769147872925 100 +8.201447457075119 100 +4.810229122638702 100 +13.624854683876038 10 +0.02141737937927246 100 +9.210374534130096 100 +0.8272840976715088 100 +7.44002890586853 100 +#HACK STRING EVAL +6.024465203285217 100 +3.588631331920624 100 +10.225892186164856 100 +7.569956421852112 100 +9.025194227695465 100 +7.063286900520325 100 +7.61640465259552 100 +9.021850526332855 100 +2.1948640048503876 100 +8.208735316991806 100 +#HACK STRING EVAL +4.58662885427475 100 +9.34461784362793 100 +9.34897780418396 100 +4.251765996217728 100 +9.294995903968811 100 +9.416532009840012 100 +8.972472846508026 100 +6.612744390964508 100 +4.340914875268936 100 +9.14776211977005 100 +#HACK STRING EVAL +4.096772491931915 100 +7.763455927371979 100 +7.122115463018417 100 +10.747573226690292 100 +6.556640028953552 100 +7.911916613578796 100 +6.523254990577698 100 +8.355346381664276 100 +7.604189217090607 100 +3.6869091391563416 100 +#HACK STRING EVAL +-3.7503671646118164 100 +-6.669588088989258 100 +-7.995953559875488 100 +-4.92095947265625 100 +-6.310798645019531 100 +-4.496591567993164 100 +-9.074676990509033 100 +-2.968735694885254 100 +-5.535251617431641 100 +-5.104723930358887 100 +#HACK STRING EVAL +5.259403705596924 100 +4.120326638221741 100 +-1.5642900466918945 100 +9.496643900871277 100 +4.817384243011475 100 +0.2672262191772461 100 +-0.4502830505371094 100 +-0.944915771484375 100 +6.663272976875305 100 +8.447489023208618 100 +#HACK STRING EVAL +9.794468015432358 100 +8.695936247706413 100 +8.195095121860504 100 +5.021435782313347 100 +7.623250588774681 100 +11.060578405857086 100 +9.903262197971344 100 +7.67883113026619 100 +6.067329987883568 100 +6.829614698886871 100 +#HACK STRING EVAL +6.263217806816101 7 +7.927499279379845 9 +4.413127601146698 4 +7.859428107738495 10 +10.771553456783295 100 +9.620209284126759 100 +7.219764351844788 100 +8.040100246667862 9 +10.115781962871552 9 +2.81003737449646 4 +#HACK STRING EVAL +6.493276447057724 100 +5.553814709186554 100 +8.807341694831848 7 +0.8437857329845428 100 +8.29658654332161 100 +5.850256487727165 100 +4.3092003762722015 100 +7.497375786304474 100 +7.545320808887482 100 +1.5094772577285767 100 +#HACK STRING EVAL +7.676556050777435 100 +3.00021892786026 100 +9.514983654022217 100 +5.918086349964142 100 +10.862872570753098 100 +7.596287101507187 100 +10.20506888628006 100 +6.744036555290222 100 +1.865432322025299 100 +5.866290509700775 100 +#HACK STRING EVAL +4.682426363229752 100 +4.965771794319153 100 +8.611242949962616 100 +10.692781627178192 100 +12.012783408164978 100 +1.9110969603061676 100 +12.114648461341858 100 +8.964379519224167 100 +8.825770318508148 8 +5.371029257774353 100 +#HACK STRING EVAL +5.925447404384613 100 +3.578967809677124 100 +2.7296950817108154 100 +3.217819094657898 100 +8.841796845197678 100 +6.879958987236023 100 +6.400086283683777 100 +10.933216333389282 100 +8.885370433330536 100 +9.528064966201782 10 +#HACK STRING EVAL +8.212002038955688 100 +7.8497923612594604 100 +5.409816175699234 100 +1.2804740071296692 100 +8.257034987211227 100 +5.481799960136414 100 +2.5813915133476257 100 +6.999538898468018 100 +5.46000799536705 100 +4.65582150220871 100 +#HACK STRING EVAL +8.266899079084396 100 +2.8260650038719177 100 +7.935536473989487 100 +7.620114684104919 100 +9.26899242401123 100 +12.414115071296692 100 +9.312488555908203 100 +6.867390424013138 100 +10.774770259857178 100 +5.398264706134796 100 +#HACK STRING EVAL +8.927051365375519 100 +8.684166103601456 100 +11.175861597061157 100 +7.765497773885727 100 +2.644650399684906 100 +8.49767380952835 100 +9.168276071548462 100 +5.388116300106049 100 +3.5001091957092285 100 +6.267937183380127 100 +#HACK STRING EVAL +5.104865074157715 100 +12.688398331403732 100 +9.625003397464752 100 +7.186102032661438 100 +10.673939228057861 100 +3.6090114414691925 100 +1.0620544850826263 100 +5.83232444524765 100 +11.410576283931732 100 +9.211527228355408 100 +#HACK STRING EVAL +5.830496788024902 100 +10.534457296133041 100 +11.097974270582199 100 +4.05108106136322 100 +11.644344627857208 100 +3.0626412630081177 100 +9.28789895772934 100 +4.911107093095779 100 +8.599743366241455 100 +8.233198642730713 100 +#HACK STRING EVAL +10.629609048366547 100 +9.428372085094452 100 +11.028716325759888 100 +5.564973682165146 100 +8.718613624572754 100 +9.100385248661041 100 +8.056908309459686 100 +9.904407799243927 100 +5.451881796121597 100 +7.400193989276886 100 +#HACK STRING EVAL +8.385548412799835 100 +2.3897805511951447 100 +11.906824231147766 100 +4.081909656524658 100 +7.6416327357292175 100 +8.014281272888184 100 +8.267926841974258 100 +9.727721571922302 100 +7.424173593521118 100 +12.473462700843811 100 +#HACK STRING EVAL +3.796173334121704 100 +6.461186051368713 100 +10.94147104024887 100 +7.904167175292969 100 +4.57301789522171 100 +13.456120550632477 100 +-0.2192578911781311 100 +9.546552002429962 100 +1.1644489765167236 100 +7.687458872795105 100 +#HACK STRING EVAL +5.894013375043869 100 +3.784391462802887 100 +9.800707638263702 100 +7.76475590467453 100 +9.144356042146683 100 +7.012299716472626 100 +7.880287051200867 100 +8.771510243415833 100 +2.1477117240428925 100 +8.327784448862076 100 +#HACK STRING EVAL +4.742848813533783 100 +9.217926681041718 100 +9.651117622852325 100 +4.8965513706207275 100 +9.105375111103058 100 +9.717262327671051 100 +9.292214572429657 100 +6.924942433834076 100 +4.071407109498978 100 +8.878873825073242 100 +#HACK STRING EVAL +3.9501596093177795 100 +7.890439480543137 100 +6.6983227133750916 100 +10.527984380722046 100 +6.668783247470856 100 +7.682249009609222 100 +6.072095960378647 100 +8.859081208705902 100 +7.372483134269714 100 +3.922191023826599 100 +#HACK STRING EVAL +-3.7503671646118164 100 +-6.669588088989258 100 +-7.995953559875488 100 +-4.92095947265625 100 +-6.310798645019531 100 +-4.496591567993164 100 +-9.295823574066162 100 +-2.968735694885254 100 +-5.535251617431641 100 +-5.104723930358887 100 +#HACK STRING EVAL +6.4603007435798645 7 +5.064473390579224 100 +8.129438072443008 100 +10.4404818713665 100 +5.761219725012779 100 +9.960954457521439 100 +9.243445068597794 100 +8.748812347650528 100 +7.60710683465004 100 +9.663569152355194 9 +#HACK STRING EVAL +9.369730278849602 100 +8.747187733650208 7 +7.770357429981232 100 +4.79722997546196 100 +7.399044752120972 100 +10.635840639472008 100 +9.679056406021118 100 +7.454625308513641 100 +5.843124181032181 100 +6.605408728122711 100 +#HACK STRING EVAL +5.740779876708984 100 +7.386395841836929 100 +3.881651520729065 100 +7.9018020033836365 8 +10.483524471521378 100 +9.352689802646637 100 +6.912493169307709 100 +7.452454030513763 100 +9.603672832250595 100 +2.209382951259613 100 +#HACK STRING EVAL +6.58673158288002 100 +5.433573484420776 100 +8.123187273740768 100 +0.7817411720752716 100 +8.12682569026947 100 +5.6513877511024475 100 +4.1104497611522675 100 +7.454110145568848 100 +7.425079345703125 100 +1.495276689529419 100 +#HACK STRING EVAL +7.541355907917023 100 +3.056636095046997 100 +9.367072403430939 100 +5.614948719739914 100 +10.727646827697754 100 +7.839324951171875 100 +10.057124495506287 100 +6.8132354617118835 100 +1.7302913069725037 100 +5.905005723237991 100 +#HACK STRING EVAL +4.874047815799713 100 +4.91840672492981 100 +8.425363093614578 100 +10.723045825958252 100 +12.209388077259064 100 +1.8637317419052124 100 +12.26438245177269 100 +9.103379845619202 100 +8.217237800359726 100 +5.185258001089096 100 +#HACK STRING EVAL +5.972980558872223 100 +3.716737389564514 100 +2.7941703498363495 100 +3.145590841770172 100 +8.690180242061615 100 +6.807874441146851 100 +6.538370490074158 100 +11.1693474650383 100 +9.122042119503021 100 +8.67293205857277 100 +#HACK STRING EVAL +8.09392935037613 100 +7.99120420217514 100 +5.575427711009979 100 +1.4211065769195557 100 +8.149155765771866 100 +5.278126955032349 100 +2.0706804394721985 100 +6.889333814382553 100 +5.256814658641815 100 +4.821133613586426 100 +#HACK STRING EVAL +8.284076035022736 100 +2.8436012268066406 100 +7.960426449775696 100 +7.907259881496429 100 +9.663235425949097 100 +12.434091567993164 100 +9.707679212093353 100 +6.761891961097717 100 +10.669309377670288 100 +5.483723163604736 100 +#HACK STRING EVAL +8.979512572288513 100 +9.041517436504364 100 +11.51957631111145 100 +7.529394030570984 100 +3.008830487728119 100 +8.532917559146881 100 +9.203302145004272 100 +5.164875745773315 100 +3.535431385040283 100 +6.304210186004639 100 +#HACK STRING EVAL +4.98761123418808 100 +12.865154504776001 100 +9.800200700759888 100 +6.821043968200684 100 +10.926341533660889 100 +3.860010266304016 100 +0.673616349697113 100 +5.484777212142944 100 +11.585563480854034 100 +9.451239466667175 100 +#HACK STRING EVAL +6.23457607626915 100 +10.424365222454071 100 +10.734930515289307 100 +3.9161460399627686 100 +11.461744844913483 100 +2.8433675169944763 100 +9.178721517324448 100 +5.204046249389648 100 +9.001113921403885 100 +8.429160684347153 100 +#HACK STRING EVAL +10.701921701431274 100 +9.517499148845673 100 +10.627815663814545 100 +5.311403930187225 100 +8.591140806674957 100 +9.038008391857147 100 +8.322645127773285 100 +10.20224529504776 100 +5.2803356647491455 100 +7.510595619678497 100 +#HACK STRING EVAL +7.840290039777756 100 +2.864722967147827 100 +11.376970112323761 100 +4.220048189163208 100 +8.00537896156311 100 +8.445551872253418 100 +8.696987748146057 100 +9.172305405139923 100 +7.541157126426697 100 +11.968105137348175 100 +#HACK STRING EVAL +3.92233806848526 100 +6.314629435539246 100 +10.99165141582489 100 +8.1087846159935 100 +4.971502423286438 100 +13.30996060371399 100 +-0.08609351515769958 100 +9.375309407711029 100 +0.992313027381897 100 +7.352379679679871 100 +#HACK STRING EVAL +6.176911413669586 100 +3.7284610271453857 100 +10.24110460281372 100 +7.7051562666893005 100 +8.702153325080872 100 +7.082029759883881 100 +7.857144773006439 100 +8.745163083076477 100 +2.223482996225357 100 +7.86816668510437 100 +#HACK STRING EVAL +4.769678235054016 100 +9.427928984165192 100 +8.981187403202057 100 +4.228182315826416 100 +8.939100444316864 100 +9.061281085014343 100 +8.624100297689438 100 +6.478103399276733 100 +4.7438205778598785 100 +9.553712993860245 100 +#HACK STRING EVAL +4.293291062116623 100 +7.570051968097687 100 +6.873266845941544 100 +10.532938539981842 100 +6.3426743149757385 100 +7.660526752471924 100 +6.407741189002991 100 +8.764895349740982 100 +7.377267479896545 100 +3.9109861850738525 100 +#HACK STRING EVAL +-3.7503671646118164 100 +-6.669588088989258 100 +-7.995953559875488 100 +-4.92095947265625 100 +-6.310798645019531 100 +-4.496591567993164 100 +-9.295823574066162 100 +-2.968735694885254 100 +-5.535251617431641 100 +-5.104723930358887 100 +#HACK STRING EVAL +6.351260147988796 100 +5.211845874786377 100 +8.276810675859451 100 +10.587854415178299 100 +5.90859217196703 100 +10.108326941728592 100 +9.390817672014236 100 +8.89618495106697 100 +7.7544794380664825 100 +9.53870202600956 100 +#HACK STRING EVAL +9.712917804718018 100 +8.614386081695557 100 +8.113544911146164 100 +4.939885675907135 100 +7.5417004227638245 100 +10.979028210043907 100 +9.821712106466293 100 +7.597281038761139 100 +5.985779821872711 100 +6.7480645179748535 100 +#HACK STRING EVAL +5.808571428060532 100 +7.94852352142334 8 +3.936764359474182 100 +7.900054335594177 8 +10.51252007484436 100 +9.407802820205688 100 +7.006955564022064 100 +7.5861144959926605 100 +10.102851033210754 8 +2.808748722076416 3 +#HACK STRING EVAL +6.3685769736766815 100 +5.642427325248718 100 +8.332041144371033 100 +0.6053363382816315 100 +8.016387522220612 100 +5.80424439907074 100 +4.070750743150711 100 +7.585988432168961 100 +7.633933424949646 100 +1.3847777247428894 100 +#HACK STRING EVAL +7.679065525531769 100 +2.9423453211784363 100 +9.25278639793396 100 +5.92059588432312 100 +10.854549765586853 100 +7.548945367336273 100 +9.942895531654358 100 +6.940076768398285 100 +1.613768756389618 100 +5.614626824855804 100 +#HACK STRING EVAL +4.55692645907402 100 +5.066379725933075 100 +8.323158115148544 100 +10.500874817371368 100 +12.110844910144806 100 +2.0966500639915466 100 +12.359699010848999 100 +8.785079777240753 100 +8.118250787258148 100 +5.084404557943344 100 +#HACK STRING EVAL +5.818827360868454 100 +3.971997767686844 100 +2.4242513477802277 100 +3.516967535018921 100 +8.432523310184479 100 +7.179113745689392 100 +6.793064624071121 100 +10.799787282943726 100 +8.751947700977325 100 +9.043717503547668 100 +#HACK STRING EVAL +8.09262415766716 100 +8.367267191410065 100 +5.920927047729492 100 +1.782512903213501 100 +8.137710809707642 100 +5.62790310382843 100 +2.4625004827976227 100 +6.4940566420555115 100 +5.608422040939331 100 +4.472492754459381 100 +#HACK STRING EVAL +8.310888051986694 100 +3.317253440618515 100 +8.426750421524048 100 +7.423366695642471 100 +9.31619331240654 100 +12.905340045690536 100 +9.423402696847916 100 +6.670658230781555 100 +11.007360368967056 100 +5.132082581520081 100 +#HACK STRING EVAL +8.64703232049942 100 +8.729335486888885 100 +10.923555076122284 100 +7.221434950828552 100 +2.6896822452545166 100 +7.948668539524078 100 +8.607363671064377 100 +4.827719807624817 100 +2.9536372423171997 100 +6.183122098445892 100 +#HACK STRING EVAL +4.488203704357147 100 +12.518753409385681 100 +9.450329899787903 100 +6.603563010692596 100 +11.247668147087097 100 +4.222058683633804 100 +0.47929155826568604 100 +5.703612238168716 100 +11.671492755413055 100 +9.77050057053566 100 +#HACK STRING EVAL +5.6928543746471405 100 +9.885874271392822 100 +10.394038677215576 100 +4.259725511074066 100 +12.027608811855316 100 +2.410770356655121 100 +8.9828479886055 100 +5.60553765296936 100 +8.452967762947083 100 +8.094914078712463 100 +#HACK STRING EVAL +10.731662958860397 100 +9.330437779426575 100 +10.80081969499588 100 +5.3582873940467834 100 +8.913542538881302 100 +9.195272356271744 100 +8.256003558635712 100 +10.487058818340302 100 +4.875956177711487 100 +7.211015105247498 100 +#HACK STRING EVAL +8.029483944177628 100 +2.8313759565353394 100 +11.551618993282318 100 +4.168847024440765 100 +7.992243647575378 100 +8.460192859172821 100 +8.641214787960052 100 +9.335831761360168 100 +7.434365153312683 100 +12.008463740348816 100 +#HACK STRING EVAL +3.776666045188904 100 +5.903277188539505 100 +11.060274243354797 100 +8.01528924703598 100 +5.102793514728546 100 +12.886958241462708 100 +0.3114774227142334 100 +9.440798699855804 100 +1.0471412539482117 100 +7.12617152929306 100 +#HACK STRING EVAL +6.183504372835159 100 +3.926165997982025 100 +10.025192022323608 100 +7.8986639976501465 100 +8.661369025707245 100 +6.865338563919067 100 +7.72868287563324 100 +8.65654855966568 100 +2.047849714756012 100 +7.835327506065369 100 +#HACK STRING EVAL +4.771426439285278 100 +9.250211119651794 100 +9.111227333545685 100 +4.365838587284088 100 +9.138639330863953 100 +9.182050585746765 100 +8.758071184158325 100 +6.390210390090942 100 +4.577596098184586 100 +9.388151377439499 100 +#HACK STRING EVAL +4.2138842940330505 100 +7.867364674806595 100 +6.758310854434967 100 +10.376049965620041 100 +6.45916223526001 100 +7.803810358047485 100 +6.206468999385834 100 +8.804630845785141 100 +7.497429728507996 100 +3.8051507472991943 100 +#HACK STRING EVAL +10.295404978096485 68 +-5.901884078979492 100 +6.04949913918972 59 +9.1265429854393 58 +7.736144877970219 55 +9.548147223889828 58 +4.748154237866402 51 +11.074349477887154 54 +8.51038222014904 65 +8.938352428376675 51 +#HACK STRING EVAL +6.142683327198029 100 +5.003269016742706 100 +8.068233698606491 100 +10.379277482628822 100 +5.7000152468681335 100 +9.899749964475632 100 +9.182240694761276 100 +8.68760797381401 100 +7.545902445912361 100 +9.669454455375671 11 +#HACK STRING EVAL +9.869107522070408 12 +8.729442201554775 10 +8.255895413458347 11 +5.101813450455666 7 +7.730541206896305 9 +11.13311892747879 11 +9.938515782356262 10 +7.716077335178852 9 +6.099257469177246 7 +6.883736856281757 11 +#HACK STRING EVAL +5.7495143711566925 100 +7.935916304588318 8 +3.9165031909942627 100 +7.85318249464035 8 +10.492258861660957 100 +9.387541472911835 100 +6.959705352783203 100 +7.527057409286499 100 +9.611133694648743 100 +2.8588727712631226 3 +#HACK STRING EVAL +6.471364825963974 100 +5.531902968883514 100 +8.245159089565277 100 +0.690016582608223 100 +8.14281752705574 100 +5.696487188339233 100 +4.155431270599365 100 +8.036793172359467 7 +7.5234090983867645 100 +1.4875655770301819 100 +#HACK STRING EVAL +7.454838931560516 100 +3.0340821743011475 100 +9.55017876625061 100 +5.696369156241417 100 +10.752266615629196 100 +7.8358044028282166 100 +10.094464391469955 100 +6.726641356945038 100 +1.900627762079239 100 +5.901485860347748 100 +#HACK STRING EVAL +4.742548584938049 100 +5.0665165185928345 100 +8.361680388450623 100 +10.59154662489891 100 +12.145358383655548 100 +2.0118416845798492 100 +12.247225791215897 100 +8.902379393577576 100 +8.153184652328491 100 +5.745859980583191 6 +#HACK STRING EVAL +5.97123584151268 100 +3.7113121151924133 100 +2.5847914814949036 100 +3.3606480956077576 100 +8.696889340877533 100 +7.022795081138611 100 +6.542918801307678 100 +10.951798141002655 100 +8.912482351064682 100 +9.551307916641235 10 +#HACK STRING EVAL +7.91670423746109 100 +8.150247156620026 100 +5.729820489883423 100 +1.5809212625026703 100 +7.96174544095993 100 +5.431876003742218 100 +2.264487236738205 100 +6.704252004623413 100 +5.410647451877594 100 +4.674331068992615 100 +#HACK STRING EVAL +8.520756304264069 100 +3.1245142817497253 100 +8.278864979743958 100 +7.624560654163361 100 +9.526770770549774 100 +12.712597489356995 100 +9.610824048519135 100 +6.871909916400909 100 +10.765697300434113 100 +5.397839546203613 100 +#HACK STRING EVAL +8.825726091861725 100 +9.050928592681885 100 +11.10233411192894 100 +7.383278548717499 100 +3.011121928691864 100 +8.27668583393097 100 +8.786146104335785 100 +5.1671212911605835 100 +3.122569441795349 100 +5.887210249900818 100 +#HACK STRING EVAL +4.6208436489105225 100 +12.75547668337822 100 +9.693972527980804 100 +6.702263295650482 100 +11.034947454929352 100 +3.9730533957481384 100 +0.578234076499939 100 +5.58140504360199 100 +11.480725586414337 100 +9.705960869789124 100 +#HACK STRING EVAL +5.950536549091339 100 +10.018041372299194 100 +10.710181385278702 100 +3.874565064907074 100 +11.761321008205414 100 +2.5462030172348022 100 +9.197569966316223 100 +5.294146299362183 100 +8.592719495296478 100 +8.353468596935272 100 +#HACK STRING EVAL +10.414941132068634 100 +9.662935316562653 100 +10.5525484085083 100 +5.36851292848587 100 +8.829681783914566 100 +8.889036267995834 100 +8.590047061443329 100 +10.391769826412201 100 +4.97442752122879 100 +7.635888338088989 100 +#HACK STRING EVAL +8.133445262908936 100 +2.8777331113815308 100 +11.4295494556427 100 +4.070798814296722 100 +8.104539930820465 100 +8.289444416761398 100 +8.756578385829926 100 +9.239134132862091 100 +7.473095655441284 100 +12.025636851787567 100 +#HACK STRING EVAL +3.8547691106796265 100 +5.975614607334137 100 +10.91149091720581 100 +7.858363747596741 100 +4.8182133436203 100 +12.968066811561584 100 +0.26480770111083984 100 +9.611122190952301 100 +1.218489944934845 100 +7.115846753120422 100 +#HACK STRING EVAL +6.484213799238205 100 +3.824646234512329 100 +10.150813937187195 100 +8.022388398647308 100 +9.03385666012764 100 +6.7701863050460815 100 +7.8565831780433655 100 +9.031816184520721 100 +1.9244375824928284 100 +7.991164445877075 100 +#HACK STRING EVAL +5.064118444919586 100 +9.18656051158905 100 +9.2133948802948 100 +4.458944857120514 100 +9.152779221534729 100 +9.27969142794609 100 +8.854684829711914 100 +6.487395107746124 100 +4.816895425319672 100 +9.315160512924194 100 +#HACK STRING EVAL +4.444510847330093 100 +7.6426825523376465 100 +6.97995787858963 100 +10.612756073474884 100 +6.198649823665619 100 +7.543570458889008 100 +6.143175840377808 100 +8.560078918933868 100 +7.234822630882263 100 +4.048377424478531 100 +#HACK STRING EVAL +-3.7503671646118164 100 +-6.669588088989258 100 +-7.995953559875488 100 +-4.92095947265625 100 +-6.310798645019531 100 +-4.496591567993164 100 +-9.295823574066162 100 +-2.968735694885254 100 +-5.535251617431641 100 +-5.104723930358887 100 +#HACK STRING EVAL +6.4530118852853775 16 +5.317180283367634 14 +8.416674345731735 12 +10.687089890241623 27 +6.011694967746735 19 +10.221041649580002 13 +9.520711466670036 13 +9.045291796326637 13 +7.857538290321827 19 +9.64567582309246 25 +#HACK STRING EVAL +9.64411398768425 100 +8.758316919207573 10 +8.247497245669365 9 +4.927807554602623 100 +7.529622212052345 100 +10.966950073838234 100 +9.953981220722198 10 +7.756882727146149 8 +5.97370158135891 100 +6.899004518985748 7 +#HACK STRING EVAL +5.765783190727234 100 +7.447952061891556 100 +4.0863951444625854 100 +7.402050822973251 100 +10.508527591824532 100 +9.557433366775513 100 +7.003365337848663 100 +7.543326169252396 100 +9.62547755241394 100 +2.8002865314483643 3 +#HACK STRING EVAL +6.416379541158676 100 +5.476917803287506 100 +8.283450484275818 100 +0.6556916832923889 100 +8.064189821481705 100 +5.7347787618637085 100 +4.193722635507584 100 +7.420478522777557 100 +7.585342764854431 100 +1.432580292224884 100 +#HACK STRING EVAL +7.552596151828766 100 +3.052884578704834 100 +9.363322377204895 100 +6.377645432949066 6 +10.738907188177109 100 +7.748382925987244 100 +10.053431510925293 100 +6.824398636817932 100 +1.8132063150405884 100 +5.742338240146637 100 +#HACK STRING EVAL +4.525786578655243 100 +5.252383291721344 100 +8.293033003807068 100 +10.376002877950668 100 +12.077133595943451 100 +2.0377669632434845 100 +12.180066347122192 100 +8.976229161024094 100 +8.147208511829376 100 +5.29150664806366 100 +#HACK STRING EVAL +6.05828583240509 100 +3.804209589958191 100 +2.6637142300605774 100 +3.394270420074463 100 +8.598381340503693 100 +6.986108720302582 100 +6.6253273487091064 100 +11.039245545864105 100 +8.991400212049484 100 +8.850717335939407 100 +#HACK STRING EVAL +7.908849895000458 100 +8.18338930606842 100 +5.74272358417511 100 +1.486157089471817 100 +8.074092328548431 100 +5.445938766002655 100 +2.277602344751358 100 +6.696139693260193 100 +5.424767374992371 100 +4.665685743093491 100 +#HACK STRING EVAL +8.587570428848267 100 +3.0066340565681458 100 +8.254606127738953 100 +7.756431996822357 100 +9.586878597736359 100 +12.594680368900299 100 +9.601825267076492 100 +6.878193527460098 100 +10.647778272628784 100 +5.529485821723938 100 +#HACK STRING EVAL +8.796467334032059 100 +8.860104978084564 100 +11.304572075605392 100 +7.354011029005051 100 +2.817750632762909 100 +8.359479367733002 100 +8.98611718416214 100 +4.975434243679047 100 +3.087076634168625 100 +6.085272133350372 100 +#HACK STRING EVAL +4.852855086326599 100 +12.63730263710022 100 +9.660245716571808 100 +6.9342599511146545 100 +10.927123963832855 100 +4.0192201137542725 100 +0.810231477022171 100 +5.5014051496982574 100 +11.446055054664612 100 +9.464745938777924 100 +#HACK STRING EVAL +6.024975657463074 100 +10.219615757465363 100 +10.567976653575897 100 +4.099961161613464 100 +11.643817663192749 100 +2.747816801071167 100 +9.340564727783203 100 +5.440703392028809 100 +8.572190940380096 100 +8.204661071300507 100 +#HACK STRING EVAL +10.723904550075531 100 +9.46678626537323 100 +10.814222931861877 100 +5.103324711322784 100 +8.564855754375458 100 +9.196213901042938 100 +8.278520226478577 100 +10.25811979174614 100 +5.235917150974274 100 +7.442923009395599 100 +#HACK STRING EVAL +7.976974189281464 100 +2.6219229698181152 100 +11.675251483917236 100 +4.116932392120361 100 +8.145518153905869 100 +8.33664333820343 100 +8.58897078037262 100 +9.391990900039673 100 +7.217754244804382 100 +12.078132331371307 100 +#HACK STRING EVAL +3.9564571380615234 100 +6.084263205528259 100 +11.125262200832367 100 +8.085101068019867 100 +4.935422122478485 100 +13.083335936069489 100 +0.13901978731155396 100 +9.40069454908371 100 +1.0005435347557068 100 +7.30644690990448 100 +#HACK STRING EVAL +6.367919206619263 100 +3.7194005250930786 100 +10.249884486198425 100 +7.736096799373627 100 +8.868078649044037 100 +7.046898603439331 100 +7.78671658039093 100 +8.861260831356049 100 +2.2259711623191833 100 +8.048677384853363 100 +#HACK STRING EVAL +4.6711665987968445 100 +9.188750863075256 100 +9.207400143146515 100 +4.446186393499374 100 +9.060037195682526 100 +9.272927045822144 100 +8.8481964468956 100 +6.494815707206726 100 +4.438453316688538 100 +9.292011439800262 100 +#HACK STRING EVAL +4.252095729112625 100 +7.562578976154327 100 +6.953298807144165 100 +10.554653286933899 100 +6.420227766036987 100 +7.701142281293869 100 +6.335337996482849 100 +8.618912994861603 100 +7.411568462848663 100 +3.8515877723693848 100 +#HACK STRING EVAL +-1.0958404541015625 100 +-4.015061378479004 100 +-5.341426849365234 100 +-2.266432762145996 100 +-3.6562719345092773 100 +-1.8420648574829102 100 +-6.641296863555908 100 +-0.3142099380493164 100 +-2.8807249069213867 100 +-2.450198173522949 100 +#HACK STRING EVAL +6.37677501142025 100 +5.237360700964928 100 +8.302325397729874 100 +10.613369211554527 100 +5.9341070502996445 100 +10.133841663599014 100 +9.416332393884659 100 +8.921699672937393 100 +7.779994234442711 100 +9.56421683728695 100 +#HACK STRING EVAL +9.826202869415283 11 +8.761402636766434 9 +8.223835870623589 11 +5.099700450897217 6 +7.712015330791473 8 +11.11523026227951 10 +9.950980693101883 12 +7.737202696502209 10 +6.135625034570694 8 +6.928832605481148 8 +#HACK STRING EVAL +5.755610167980194 100 +7.931841015815735 8 +4.445832431316376 4 +7.386507764458656 100 +10.492984548211098 100 +9.393637329339981 100 +6.9931923896074295 100 +7.533153370022774 100 +9.639250546693802 100 +2.8512452840805054 3 +#HACK STRING EVAL +6.479508265852928 100 +5.540046691894531 100 +8.229684382677078 100 +0.7250793129205704 100 +8.12731847167015 100 +5.681012570858002 100 +4.139956474304199 100 +7.4836317002773285 100 +7.531576752662659 100 +1.495709240436554 100 +#HACK STRING EVAL +7.513329207897186 100 +3.098145216703415 100 +9.408583521842957 100 +5.813935548067093 100 +10.69964063167572 100 +7.674473285675049 100 +10.078933149576187 100 +6.785133481025696 100 +1.702203780412674 100 +5.74015474319458 100 +#HACK STRING EVAL +4.7033242881298065 100 +5.212543189525604 100 +8.470774471759796 100 +10.552322208881378 100 +12.254480540752411 100 +2.157868504524231 100 +12.876684784889221 10 +8.93265163898468 100 +8.267309933900833 100 +5.100020170211792 100 +#HACK STRING EVAL +5.87896004319191 100 +3.6942827105522156 100 +2.484386384487152 100 +3.4627700448036194 100 +8.536884874105453 100 +7.171248078346252 100 +6.51529735326767 100 +10.974985957145691 100 +8.812072277069092 100 +9.03620821237564 100 +#HACK STRING EVAL +7.836580872535706 100 +8.228728264570236 100 +5.7887242436409 100 +1.6594005823135376 100 +7.881608873605728 100 +5.358270466327667 100 +2.195276230573654 100 +6.613218367099762 100 +5.469641387462616 100 +4.756158649921417 100 +#HACK STRING EVAL +8.651199281215668 100 +3.210370033979416 100 +8.319846868515015 100 +7.5302654504776 100 +9.597444415092468 100 +12.79842334985733 100 +9.530211746692657 100 +6.82932186126709 100 +10.733847826719284 100 +5.303331792354584 100 +#HACK STRING EVAL +8.761351466178894 100 +8.959104120731354 100 +11.037961602210999 100 +7.4527159333229065 100 +2.923178553581238 100 +8.051590323448181 100 +8.721735835075378 100 +5.085980951786041 100 +3.341145396232605 100 +5.822749495506287 100 +#HACK STRING EVAL +4.601168930530548 100 +12.853741228580475 100 +9.776053786277771 100 +6.682174324989319 100 +10.95552271604538 100 +4.09155148267746 100 +0.5578394532203674 100 +5.396211266517639 100 +11.5628981590271 100 +9.693811357021332 100 +#HACK STRING EVAL +5.9702030420303345 100 +9.902175486087799 100 +10.73190462589264 100 +3.7584232687950134 100 +11.93516692519188 100 +2.4298449754714966 100 +8.995915651321411 100 +5.279526472091675 100 +8.478213131427765 100 +8.353365659713745 100 +#HACK STRING EVAL +10.572410345077515 100 +9.517087459564209 100 +10.500700235366821 100 +5.256678193807602 100 +8.855888217687607 100 +8.88368609547615 100 +8.577611565589905 100 +10.417326420545578 100 +4.9206026792526245 100 +7.488176465034485 100 +#HACK STRING EVAL +7.831659018993378 100 +2.9298552870750427 100 +11.351887345314026 100 +4.029556632041931 100 +7.810521632432938 100 +8.5658358335495 100 +8.807360351085663 100 +9.152328729629517 100 +7.532676339149475 100 +11.948279440402985 100 +#HACK STRING EVAL +3.9551681876182556 100 +5.733224630355835 100 +11.142510771751404 100 +8.101225078105927 100 +5.257506191730499 100 +12.725098371505737 100 +0.4708472490310669 100 +9.137883007526398 100 +0.995256245136261 100 +7.316704273223877 100 +#HACK STRING EVAL +6.347097218036652 100 +3.6138004660606384 100 +10.357052683830261 100 +7.687389254570007 100 +8.892777681350708 100 +7.202136695384979 100 +8.053368896245956 100 +8.884002566337585 100 +2.341727167367935 100 +8.0729700922966 100 +#HACK STRING EVAL +4.923095464706421 100 +9.116259515285492 100 +8.88062596321106 100 +4.126091420650482 100 +8.82525435090065 100 +8.946790903806686 100 +8.739864230155945 100 +6.154476821422577 100 +4.833368390798569 100 +9.641515135765076 100 +#HACK STRING EVAL +4.291601240634918 100 +7.571481645107269 100 +6.881875067949295 100 +10.462118744850159 100 +6.278902530670166 100 +7.640418231487274 100 +6.245940208435059 100 +8.70500272512436 100 +7.349498629570007 100 +3.964806020259857 100 +#HACK STRING EVAL +-3.7503671646118164 100 +-6.669588088989258 100 +-7.995953559875488 100 +-4.92095947265625 100 +-6.310798645019531 100 +-4.496591567993164 100 +-9.295823574066162 100 +-2.968735694885254 100 +-5.535251617431641 100 +-5.104723930358887 100 +#HACK STRING EVAL +6.308339908719063 100 +5.1689255982637405 100 +8.23389020562172 100 +10.54493410885334 100 +5.865671947598457 100 +10.065406411886215 100 +9.34789714217186 100 +8.853264421224594 100 +7.858026087284088 18 +9.495781734585762 100 +#HACK STRING EVAL +9.864393323659897 11 +8.712426863610744 100 +8.244798719882965 9 +5.1217151284217834 6 +7.676223695278168 8 +11.10928612947464 10 +9.919752806425095 100 +7.695321783423424 100 +6.083820581436157 100 +6.882361352443695 8 +#HACK STRING EVAL +5.731204390525818 100 +7.475170999765396 100 +3.8981930911540985 100 +7.868032671511173 9 +10.506430551409721 100 +9.369231462478638 100 +6.968786597251892 100 +7.508747458457947 100 +9.65269649028778 100 +2.311110332608223 100 +#HACK STRING EVAL +6.447099059820175 100 +5.611368954181671 100 +8.269725054502487 100 +0.6443080306053162 100 +8.094909250736237 100 +5.721053451299667 100 +4.179997801780701 100 +8.05294930934906 6 +7.602875083684921 100 +1.4632996320724487 100 +#HACK STRING EVAL +7.587017983198166 100 +3.0289596915245056 100 +9.339402496814728 100 +5.828548491001129 100 +10.773334264755249 100 +7.633500874042511 100 +10.037937581539154 100 +6.858820736408234 100 +1.7758944034576416 100 +5.699179947376251 100 +#HACK STRING EVAL +4.5843565464019775 100 +5.0885009765625 100 +9.000412344932556 7 +10.433355629444122 100 +12.135513067245483 100 +2.108940899372101 100 +12.237377166748047 100 +8.921690225601196 100 +8.218359291553497 100 +5.186655342578888 100 +#HACK STRING EVAL +5.915972411632538 100 +3.801703453063965 100 +2.5212077498435974 100 +3.403323173522949 100 +8.603383779525757 100 +7.065701246261597 100 +6.622824490070343 100 +10.896838963031769 100 +8.859898447990417 100 +8.926348060369492 100 +#HACK STRING EVAL +7.801534593105316 100 +8.247063338756561 100 +5.716971695423126 100 +1.677739143371582 100 +7.927345335483551 100 +5.419690907001495 100 +2.3415142595767975 100 +6.5894346833229065 100 +5.397974282503128 100 +4.697838306427002 100 +#HACK STRING EVAL +8.514944612979889 100 +3.129016548395157 100 +8.240860015153885 100 +7.599546700716019 100 +9.574646472930908 100 +12.72014769911766 100 +9.599662810564041 100 +6.924158751964569 100 +10.831501215696335 100 +5.33374810218811 100 +#HACK STRING EVAL +9.000285565853119 100 +8.975911915302277 100 +11.197257399559021 100 +7.469462633132935 100 +2.9364126324653625 100 +8.286312997341156 100 +8.96405702829361 100 +5.180669486522675 100 +3.289998710155487 100 +5.982125908136368 100 +#HACK STRING EVAL +4.84178900718689 100 +12.640241891145706 100 +9.711780399084091 100 +6.923382878303528 100 +11.028886139392853 100 +3.8515466451644897 100 +0.7948319911956787 100 +5.4427346885204315 100 +11.36242127418518 100 +9.452846825122833 100 +#HACK STRING EVAL +5.886930853128433 100 +10.235381007194519 100 +10.645083248615265 100 +4.084978401660919 100 +11.612814843654633 100 +2.753066062927246 100 +9.329401552677155 100 +5.1862539649009705 100 +8.811424374580383 100 +8.438677698373795 100 +#HACK STRING EVAL +10.608102321624756 100 +9.483904242515564 100 +10.74054878950119 100 +5.229961603879929 100 +8.604585468769073 100 +9.073703110218048 100 +8.318285167217255 100 +10.25160038471222 100 +5.165107548236847 100 +7.506245732307434 100 +#HACK STRING EVAL +8.002081662416458 100 +2.7421833872795105 100 +11.507658541202545 100 +4.179725229740143 100 +8.02996888756752 100 +8.369684278964996 100 +8.655596911907196 100 +9.319042086601257 100 +7.340241074562073 100 +12.131912857294083 100 +#HACK STRING EVAL +3.876878559589386 100 +6.091305196285248 100 +11.01984190940857 100 +7.98173326253891 100 +4.909506440162659 100 +13.102272093296051 100 +0.08775615692138672 100 +9.40103667974472 100 +1.1001601219177246 100 +7.328019320964813 100 +#HACK STRING EVAL +6.199662834405899 100 +3.830769896507263 100 +10.139197945594788 100 +7.727692186832428 100 +8.828437507152557 100 +7.017690658569336 100 +7.771187007427216 100 +8.811200439929962 100 +2.1104120314121246 100 +8.024953067302704 100 +#HACK STRING EVAL +4.843617677688599 100 +9.326183080673218 100 +9.076206147670746 100 +4.490494132041931 100 +9.195517718791962 100 +9.117270708084106 100 +8.786984652280807 100 +6.328778028488159 100 +4.576441317796707 100 +9.431158304214478 100 +#HACK STRING EVAL +4.223861843347549 100 +7.552930533885956 100 +6.9878687262535095 100 +10.521493673324585 100 +6.328230321407318 100 +7.6790502071380615 100 +6.376064896583557 100 +8.5492103099823 100 +7.376991391181946 100 +3.9210451245307922 100 +#HACK STRING EVAL +-3.7503671646118164 100 +-2.644322395324707 100 +-7.995953559875488 100 +-0.8956937789916992 100 +-2.2855329513549805 100 +-0.4713258743286133 100 +-5.270557880401611 100 +1.0565299987792969 100 +-5.535251617431641 100 +-1.079458236694336 100 +#HACK STRING EVAL +6.375653550028801 100 +5.236239239573479 100 +8.301204025745392 100 +10.772701412439346 13 +5.932985559105873 100 +10.132720276713371 100 +9.415210962295532 100 +8.920578300952911 100 +7.943653762340546 12 +9.5630953758955 100 +#HACK STRING EVAL +9.87265682220459 12 +8.736056320369244 10 +8.211717680096626 100 +5.086714059114456 7 +7.690808355808258 8 +11.164022356271744 12 +9.919890061020851 100 +7.695458769798279 100 +6.146687522530556 8 +6.846238441765308 100 +#HACK STRING EVAL +5.705160081386566 100 +7.563084155321121 100 +4.386534631252289 4 +7.4657077342271805 100 +10.447904527187347 100 +9.343187242746353 100 +7.0891813933849335 100 +7.629142254590988 100 +9.718450546264648 100 +2.323822110891342 100 +#HACK STRING EVAL +6.510221481323242 100 +5.571138262748718 100 +8.791184782981873 7 +0.7052311599254608 100 +8.303828686475754 100 +5.524076342582703 100 +3.983020007610321 100 +7.660117506980896 100 +7.5626444816589355 100 +1.6722187995910645 100 +#HACK STRING EVAL +7.475101292133331 100 +3.3007260262966156 100 +9.611168533563614 100 +6.349381148815155 6 +10.507210344076157 100 +7.774306774139404 100 +10.64519488811493 10 +6.592696249485016 100 +1.5097700953483582 100 +5.8399882316589355 100 +#HACK STRING EVAL +4.750488221645355 100 +5.278019905090332 100 +8.541299134492874 100 +10.599486231803894 100 +12.324989706277847 100 +1.9940108060836792 100 +12.154297828674316 100 +9.44976806640625 9 +8.103452235460281 100 +5.8140594363212585 6 +#HACK STRING EVAL +6.002609729766846 100 +3.6962203979492188 100 +2.608008623123169 100 +3.3350701928138733 100 +8.72014194726944 100 +6.9972164034843445 100 +6.479450523853302 100 +10.763640880584717 100 +8.935690760612488 100 +8.861822426319122 100 +#HACK STRING EVAL +7.9768277406692505 100 +8.084467768669128 100 +5.644421577453613 100 +1.5151310563087463 100 +8.021853029727936 100 +5.253863275051117 100 +2.087074935436249 100 +6.76433539390564 100 +5.325369894504547 100 +4.844757258892059 100 +#HACK STRING EVAL +8.42630884051323 100 +2.9854360222816467 100 +8.05368447303772 100 +7.434646040201187 100 +9.74109998345375 100 +12.573549330234528 100 +9.43228566646576 100 +6.6786070466041565 100 +10.583675622940063 100 +5.533986121416092 100 +#HACK STRING EVAL +9.025979489088058 100 +9.228975057601929 100 +11.303994089365005 100 +7.722403347492218 100 +3.1901723742485046 100 +8.456115275621414 100 +8.98837348818779 100 +5.346147805452347 100 +3.3186047673225403 100 +5.7031824588775635 100 +#HACK STRING EVAL +4.8578596115112305 100 +13.006891131401062 100 +9.944872558116913 100 +6.939484357833862 100 +10.78722608089447 100 +3.721560925245285 100 +0.8141164183616638 100 +5.20001146197319 100 +11.218632638454437 100 +9.461476385593414 100 +#HACK STRING EVAL +6.072423845529556 100 +10.220491588115692 100 +10.832929104566574 100 +3.8175763487815857 100 +11.637929081916809 100 +2.733326643705368 100 +9.30965518951416 100 +5.218861758708954 100 +8.796534240245819 100 +8.474118620157242 100 +#HACK STRING EVAL +10.315357387065887 100 +9.75434809923172 100 +10.698620617389679 100 +4.943205952644348 100 +8.680294334888458 100 +9.081141382455826 100 +8.395089507102966 100 +10.238885402679443 100 +5.121620535850525 100 +7.457138299942017 100 +#HACK STRING EVAL +7.719861030578613 100 +2.497982621192932 100 +11.802515685558319 100 +3.8734846115112305 100 +8.2713742852211 100 +8.091111302375793 100 +8.343912243843079 100 +9.602291584014893 100 +7.096492111682892 100 +11.830994248390198 100 +#HACK STRING EVAL +4.0175939202308655 100 +6.150366485118866 100 +10.95906886458397 100 +7.933630406856537 100 +4.882763624191284 100 +13.143274813890457 100 +0.08309578895568848 100 +9.54740047454834 100 +1.1562092900276184 100 +7.3707500994205475 100 +#HACK STRING EVAL +6.385776698589325 100 +3.9452326893806458 100 +10.021962761878967 100 +7.682978987693787 100 +8.975906103849411 100 +7.167330294847488 100 +7.675300657749176 100 +8.971501231193542 100 +1.9979028105735779 100 +8.16846713423729 100 +#HACK STRING EVAL +4.925402283668518 100 +9.037522584199905 100 +9.387196660041809 100 +4.590396016836166 100 +9.342490166425705 100 +9.093700468540192 100 +8.670321881771088 100 +6.652287572622299 100 +4.328314661979675 100 +9.132458508014679 100 +#HACK STRING EVAL +4.359844505786896 100 +7.798418164253235 100 +6.858332276344299 100 +10.485881298780441 100 +6.2863874435424805 100 +7.63810396194458 100 +6.23997887969017 100 +8.72694817185402 100 +7.329737365245819 100 +3.9471623301506042 100 +#HACK STRING EVAL +10.301106922328472 31 +-6.669588088989258 100 +6.067085608839989 13 +-4.92095947265625 100 +-6.310798645019531 100 +-4.496591567993164 100 +-9.295823574066162 100 +-2.968735694885254 100 +8.513264514505863 22 +-5.104723930358887 100 +#HACK STRING EVAL +6.374030143022537 100 +5.234615862369537 100 +8.299580603837967 100 +10.610624343156815 100 +5.931362181901932 100 +10.131096869707108 100 +9.413587599992752 100 +8.918954879045486 100 +7.777249366044998 100 +9.561471968889236 100 +#HACK STRING EVAL +9.831546798348427 13 +8.765242904424667 8 +8.247484982013702 10 +5.06402114033699 6 +7.66046530008316 8 +11.102871105074883 10 +9.92970559000969 12 +7.709562450647354 11 +6.101454146206379 9 +6.864111006259918 9 +#HACK STRING EVAL +5.781600087881088 100 +8.005425870418549 8 +4.451351583003998 4 +7.875800549983978 8 +10.568474501371384 100 +9.463757187128067 100 +7.01918238401413 100 +7.559143245220184 100 +10.14398980140686 8 +2.8356255292892456 3 +#HACK STRING EVAL +6.4525057673454285 100 +5.609502494335175 100 +8.299116253852844 100 +0.6475152671337128 100 +8.127038359642029 100 +5.737626761198044 100 +4.11292952299118 100 +7.553063541650772 100 +7.601008713245392 100 +1.4954286217689514 100 +#HACK STRING EVAL +7.659830987453461 100 +2.9722483158111572 100 +9.28269100189209 100 +6.403875350952148 6 +10.846147388219833 100 +7.568316459655762 100 +9.972776412963867 100 +6.924993097782135 100 +1.633139818906784 100 +5.633997976779938 100 +#HACK STRING EVAL +4.503630042076111 100 +5.282311499118805 100 +8.235986232757568 100 +10.35262906551361 100 +12.01968264579773 100 +2.2276368141174316 100 +12.474259912967682 100 +9.050571978092194 100 +8.027438133955002 100 +5.305413126945496 100 +#HACK STRING EVAL +5.7102468609809875 100 +3.984527826309204 100 +2.4222220182418823 100 +3.5102351307868958 100 +8.427774488925934 100 +7.172504186630249 100 +6.693109959363937 100 +10.977390050888062 100 +8.750239968299866 100 +9.150126963853836 100 +#HACK STRING EVAL +8.114706248044968 100 +8.34815800189972 100 +5.9493869841098785 100 +1.7788577377796173 100 +7.750313878059387 100 +5.652094900608063 100 +2.442836284637451 100 +6.49281919002533 100 +5.6303055584430695 100 +4.475945174694061 100 +#HACK STRING EVAL +8.642851412296295 100 +3.203952431678772 100 +8.32081401348114 100 +7.830358415842056 100 +9.648029088973999 100 +12.795786321163177 100 +9.53232690691948 100 +6.771093666553497 100 +10.984998732805252 100 +5.185687184333801 100 +#HACK STRING EVAL +8.790852904319763 100 +8.830203294754028 100 +11.069359302520752 100 +7.323803901672363 100 +2.7907500863075256 100 +8.087011158466339 100 +8.753325521945953 100 +4.946760833263397 100 +3.058370053768158 100 +5.857175707817078 100 +#HACK STRING EVAL +4.658800959587097 100 +12.556389033794403 100 +9.49288922548294 100 +6.72741037607193 100 +11.261385470628738 100 +4.196407586336136 100 +0.5990788340568542 100 +5.5364106595516205 100 +11.27847009897232 100 +9.383405178785324 100 +#HACK STRING EVAL +5.730556309223175 100 +10.12833058834076 100 +10.489012062549591 100 +3.956053137779236 100 +11.73499619960785 100 +2.634555220603943 100 +9.209611892700195 100 +5.5260129570961 100 +8.499801993370056 100 +8.315328478813171 100 +#HACK STRING EVAL +10.689389884471893 100 +9.343254566192627 100 +10.762006342411041 100 +5.161008536815643 100 +8.825265794992447 100 +9.148979246616364 100 +8.311778247356415 100 +10.159856796264648 100 +5.201930522918701 100 +7.317640274763107 100 +#HACK STRING EVAL +7.97722515463829 100 +2.7053288221359253 100 +11.59961873292923 100 +4.174283087253571 100 +8.064758241176605 100 +8.396976292133331 100 +8.648643612861633 100 +9.39678430557251 100 +7.340363681316376 100 +12.101705074310303 100 +#HACK STRING EVAL +4.086189299821854 100 +6.1462560296058655 100 +11.22225534915924 100 +8.186051607131958 100 +5.14985391497612 100 +13.149726688861847 100 +0.07895320653915405 100 +9.390060275793076 100 +0.9018843770027161 100 +7.434203535318375 100 +#HACK STRING EVAL +6.26042103767395 100 +3.833999991416931 100 +10.139967858791351 100 +7.814892888069153 100 +8.812249600887299 100 +6.976651847362518 100 +7.649654299020767 100 +8.807555496692657 100 +2.119396835565567 100 +8.182009994983673 100 +#HACK STRING EVAL +4.585214018821716 100 +9.194556176662445 100 +9.19372171163559 100 +4.443582713603973 100 +9.146054148674011 100 +9.277618050575256 100 +9.023573756217957 100 +6.4697853326797485 100 +4.345062255859375 100 +9.323811054229736 100 +#HACK STRING EVAL +4.501781582832336 100 +7.3791428208351135 100 +7.04487743973732 100 +10.668855249881744 100 +6.484711408615112 100 +7.826863944530487 100 +6.439125597476959 100 +8.472150146961212 100 +7.522672653198242 100 +3.7515528798103333 100 +#HACK STRING EVAL +0.3890409469604492 100 +-2.5301809310913086 100 +-3.8565454483032227 100 +-0.7815513610839844 100 +-2.1713905334472656 100 +-0.35718345642089844 100 +-5.1564154624938965 100 +1.1706733703613281 100 +-1.395843505859375 100 +-0.9653158187866211 100 +#HACK STRING EVAL +6.339734688401222 12 +5.193447530269623 10 +8.278708904981613 15 +10.630458682775497 14 +5.937879040837288 11 +10.10478825867176 20 +9.384225755929947 16 +8.856871172785759 15 +7.743979975581169 12 +9.538636818528175 16 +#HACK STRING EVAL +9.769203588366508 12 +8.689717769622803 7 +8.137401640415192 9 +5.004778623580933 7 +7.606440365314484 9 +11.012621328234673 10 +9.88770842552185 10 +7.600058078765869 8 +5.964471340179443 7 +6.803975328803062 8 +#HACK STRING EVAL +6.0839061588048935 7 +7.918565988540649 8 +4.057575911283493 100 +7.714961528778076 8 +10.891302704811096 11 +9.528614223003387 100 +7.336306929588318 8 +7.869747415184975 9 +9.967750906944275 8 +2.786799669265747 3 +#HACK STRING EVAL +6.881666302680969 7 +5.555161893367767 100 +8.732537269592285 7 +1.1405448913574219 1 +8.12850108742714 100 +5.720221638679504 100 +4.230199486017227 100 +7.92914354801178 6 +7.998696684837341 7 +1.496891438961029 100 +#HACK STRING EVAL +7.545429825782776 100 +3.080295979976654 100 +9.830857932567596 9 +6.396591484546661 6 +10.731745898723602 100 +7.669482737779617 100 +10.504579901695251 10 +6.828934550285339 100 +1.7343062162399292 100 +5.737976551055908 100 +#HACK STRING EVAL +4.637489229440689 100 +5.580276310443878 6 +8.404949396848679 100 +10.497407078742981 100 +12.188677191734314 100 +2.085684150457382 100 +12.72862195968628 10 +8.857050091028214 100 +8.196417033672333 100 +5.782142281532288 6 +#HACK STRING EVAL +5.879523575305939 100 +3.7119313180446625 100 +2.4846857488155365 100 +3.9173511266708374 4 +8.674880623817444 100 +7.109504044055939 100 +7.0639408826828 6 +11.458194255828857 9 +8.812814623117447 100 +9.4459707736969 10 +#HACK STRING EVAL +7.937023162841797 100 +8.110028445720673 100 +5.67007315158844 100 +1.5418865084648132 100 +7.9853551387786865 100 +5.38065379858017 100 +2.738826274871826 3 +6.72705602645874 100 +5.358905524015427 100 +4.70607990026474 100 +#HACK STRING EVAL +8.668018728494644 100 +3.2302706241607666 100 +8.34114682674408 100 +7.505669355392456 100 +9.475782841444016 100 +12.82119470834732 100 +9.500161170959473 100 +6.942309021949768 100 +10.849688410758972 100 +5.278791964054108 100 +#HACK STRING EVAL +8.74501484632492 100 +9.125041127204895 100 +11.37539666891098 100 +7.303603231906891 100 +2.742648661136627 100 +8.030176401138306 100 +8.706509411334991 100 +4.8987231850624084 100 +3.0387747287750244 100 +6.160115450620651 100 +#HACK STRING EVAL +5.205726504325867 4 +13.199427962303162 10 +9.536229312419891 100 +6.814453303813934 100 +11.036974966526031 100 +4.133999586105347 100 +0.683995932340622 100 +5.450949132442474 100 +11.469649314880371 100 +9.564400970935822 100 +#HACK STRING EVAL +5.7374227643013 100 +9.93188589811325 100 +10.897070825099945 100 +3.689950793981552 100 +11.941954135894775 100 +2.3624018132686615 100 +9.029399991035461 100 +5.8335771560668945 5 +8.546551883220673 100 +8.179690599441528 100 +#HACK STRING EVAL +10.431815207004547 100 +9.32051020860672 100 +10.42169776558876 100 +5.503987610340118 100 +8.833275973796844 100 +9.230060309171677 100 +8.24725353717804 100 +10.408151626586914 100 +4.95061469078064 100 +7.2898454666137695 100 +#HACK STRING EVAL +8.268616020679474 100 +2.8107863068580627 100 +11.372038900852203 100 +4.416707903146744 100 +8.091148316860199 100 +8.515515327453613 100 +8.699881732463837 100 +9.098361432552338 100 +7.482817351818085 100 +11.847678005695343 100 +#HACK STRING EVAL +4.144709646701813 100 +6.0414440631866455 100 +11.287186712026596 100 +8.24935731291771 100 +5.220844656229019 100 +13.008229672908783 100 +0.1591539978981018 100 +9.216721773147583 100 +0.8353596925735474 100 +7.489247739315033 100 +#HACK STRING EVAL +6.009699642658234 100 +3.5714718401432037 100 +10.411689579486847 100 +7.88619339466095 100 +8.62854117155075 100 +6.944068133831024 100 +7.90777051448822 100 +8.555130004882812 100 +2.380732536315918 100 +7.8948110938072205 100 +#HACK STRING EVAL +4.437211066484451 100 +9.621244430541992 62 +9.615027278661728 63 +4.862328916788101 43 +8.801672726869583 100 +9.681580424308777 25 +9.25687462091446 45 +6.8895933628082275 53 +4.941725015640259 64 +9.751338720321655 28 +#HACK STRING EVAL +3.9266363978385925 100 +7.946564257144928 100 +6.6674880385398865 100 +11.001677632331848 100 +6.708590447902679 100 +8.160216927528381 100 +6.05601504445076 100 +8.862457394599915 100 +7.850246727466583 100 +3.4722290635108948 100 +#HACK STRING EVAL +-3.7503671646118164 100 +-6.669588088989258 100 +-7.995953559875488 100 +-4.92095947265625 100 +-6.310798645019531 100 +-4.496591567993164 100 +-9.295823574066162 100 +-2.968735694885254 100 +-5.535251617431641 100 +-5.104723930358887 100 +#HACK STRING EVAL +-7.263188362121582 100 +-8.400876522064209 100 +-5.666596412658691 100 +-3.3555526733398438 100 +-8.034814834594727 100 +-3.509821891784668 100 +-4.552589416503906 100 +-5.047222137451172 100 +-6.18892765045166 100 +-4.404705047607422 100 +#HACK STRING EVAL +9.709847420454025 38 +-5.320148468017578 100 +-5.820989608764648 100 +4.952799931168556 26 +7.513680726289749 36 +10.975505143404007 45 +-4.112822532653809 100 +-6.337253570556641 100 +-7.948754787445068 100 +-7.186470031738281 100 +#HACK STRING EVAL +-7.828420639038086 100 +-6.116935729980469 100 +4.355279833078384 12 +7.785794883966446 13 +-3.0856761932373047 100 +9.846299678087234 18 +7.44268935918808 12 +-6.050877571105957 100 +-3.9394102096557617 100 +2.782930999994278 51 +#HACK STRING EVAL +5.189467072486877 100 +4.250005602836609 100 +6.939619183540344 100 +-0.615523099899292 100 +6.83727753162384 100 +4.390947461128235 100 +2.8498913049697876 100 +6.193566918373108 100 +6.241511702537537 100 +0.20566809177398682 100 +#HACK STRING EVAL +7.9034687876701355 100 +3.5235946774482727 5 +9.74189630150795 100 +6.220331490039825 7 +11.089785248041153 100 +8.201233297586441 10 +10.598096638917923 12 +7.175271183252335 100 +2.162497401237488 3 +6.093203157186508 100 +#HACK STRING EVAL +5.150334030389786 8 +5.599784925580025 8 +8.920147269964218 10 +10.968862861394882 11 +12.704810112714767 13 +2.566105604171753 3 +12.78730933368206 13 +9.529574871063232 9 +8.714890003204346 10 +5.589086547493935 7 +#HACK STRING EVAL +6.3485100865364075 6 +4.284163057804108 11 +2.933524191379547 3 +3.8941424936056137 7 +9.121413812041283 16 +7.662211328744888 9 +7.025285124778748 7 +11.377939954400063 10 +9.400222837924957 10 +9.409464299678802 11 +#HACK STRING EVAL +8.00648045539856 100 +8.281161606311798 100 +5.830618530511856 100 +1.701293259859085 100 +8.051506489515305 100 +5.5438671708106995 100 +2.8102667927742004 3 +6.794010639190674 100 +5.956687033176422 6 +4.789816975593567 100 +#HACK STRING EVAL +9.066102027893066 9 +3.236850678920746 100 +8.346321433782578 100 +7.506226360797882 100 +9.462662518024445 100 +12.8248969912529 100 +9.506158590316772 100 +6.753502279520035 100 +10.660881608724594 100 +5.496394693851471 100 +#HACK STRING EVAL +8.753596067428589 100 +8.9470134973526 100 +11.673391044139862 10 +7.883546352386475 8 +3.009553223848343 100 +8.045877635478973 100 +8.946718752384186 100 +5.539241433143616 5 +3.723831057548523 4 +5.990768671035767 100 +#HACK STRING EVAL +4.717686265707016 100 +12.920445770025253 100 +10.18174809217453 8 +6.977268636226654 100 +10.945306688547134 100 +4.001739054918289 100 +0.8532445430755615 100 +5.332152962684631 100 +11.642631739377975 100 +9.561461240053177 100 +#HACK STRING EVAL +5.963172554969788 100 +10.174188077449799 100 +10.555980145931244 100 +3.969002664089203 100 +11.592733561992645 100 +2.697163462638855 100 +9.183219760656357 100 +5.347610771656036 100 +8.514551192522049 100 +8.189678758382797 100 +#HACK STRING EVAL +10.49549400806427 100 +9.962532639503479 8 +11.348781943321228 9 +5.280179500579834 100 +9.159557342529297 9 +8.861378848552704 100 +8.864185690879822 8 +10.091517865657806 100 +5.111179947853088 100 +7.979308843612671 8 +#HACK STRING EVAL +8.18066093325615 100 +2.5191882848739624 100 +11.485883593559265 100 +4.333783507347107 100 +8.017235457897186 100 +8.929750680923462 9 +8.320774376392365 100 +9.531987756490707 100 +7.446462571620941 100 +11.959856390953064 100 +#HACK STRING EVAL +3.9915611743927 100 +5.872538089752197 100 +10.639410078525543 100 +8.486750841140747 7 +4.770526945590973 100 +13.18250459432602 100 +0.01837211847305298 100 +9.26078313589096 100 +0.965596079826355 100 +7.063904702663422 100 +#HACK STRING EVAL +6.160846710205078 100 +3.514751672744751 100 +9.85812920331955 100 +7.7244080901145935 100 +8.847133994102478 100 +6.81517106294632 100 +7.874566555023193 100 +8.989089667797089 100 +2.3776320219039917 100 +8.41051173210144 6 +#HACK STRING EVAL +4.353516340255737 100 +9.259929537773132 100 +9.692025423049927 7 +4.264478027820587 100 +9.191627979278564 100 +9.062053084373474 100 +9.301384210586548 9 +6.156458497047424 100 +4.345623195171356 100 +9.81290316581726 8 +#HACK STRING EVAL +4.768549919128418 5 +8.241695165634155 8 +6.731392204761505 100 +10.257083773612976 100 +6.344405829906464 100 +8.310279130935669 7 +6.36756357550621 100 +8.759644001722336 100 +7.1926281452178955 100 +3.9450802206993103 100 +#HACK STRING EVAL +-3.7503671646118164 100 +-6.669588088989258 100 +-7.995953559875488 100 +-4.92095947265625 100 +-6.310798645019531 100 +-4.496591567993164 100 +-9.295823574066162 100 +-2.968735694885254 100 +-5.535251617431641 100 +-5.104723930358887 100 +#HACK STRING EVAL +6.304184511303902 30 +5.165570795536041 25 +-3.333303451538086 100 +10.574669480323792 15 +5.858577787876129 28 +-1.505263328552246 100 +-2.2217464447021484 100 +-2.7144765853881836 100 +7.7043774127960205 64 +9.492864400148392 35 +#HACK STRING EVAL +9.695747688412666 17 +8.68343272805214 10 +8.15732093155384 11 +4.940624088048935 11 +7.57640814781189 13 +10.942971885204315 11 +9.896650344133377 12 +7.661856442689896 10 +6.000497460365295 8 +6.751297280192375 10 +#HACK STRING EVAL +6.152970194816589 7 +7.909104943275452 8 +4.3722986578941345 4 +7.756857007741928 9 +10.96868759393692 10 +9.831008195877075 8 +7.3899611830711365 8 +7.907551631331444 9 +10.066099047660828 8 +2.753742754459381 3 +#HACK STRING EVAL +6.6903557777404785 100 +5.987408757209778 6 +8.77486103773117 7 +1.1722527742385864 1 +8.338166236877441 100 +6.114118814468384 5 +4.31536391377449 100 +8.011822938919067 6 +7.976422369480133 7 +1.7065565586090088 100 +#HACK STRING EVAL +7.644747495651245 100 +3.1375922858715057 100 +9.866893649101257 9 +6.342599451541901 6 +10.818651139736176 100 +7.756387680768967 100 +10.138120293617249 100 +6.916549921035767 100 +1.8212110996246338 100 +5.749114036560059 100 +#HACK STRING EVAL +4.589220464229584 100 +5.630953669548035 6 +8.381467282772064 100 +10.438218295574188 100 +12.165163397789001 100 +2.174850046634674 100 +12.40361687541008 100 +9.389274060726166 9 +8.737474977970123 8 +5.621350049972534 6 +#HACK STRING EVAL +6.329891204833984 6 +3.8661499321460724 100 +2.4204854369163513 100 +3.9548550248146057 4 +8.59705275297165 100 +7.0554192662239075 100 +7.116679668426514 6 +10.995137929916382 100 +9.259684383869171 10 +9.54163384437561 10 +#HACK STRING EVAL +8.002568900585175 100 +8.233057081699371 100 +5.793035089969635 100 +1.663743644952774 100 +8.04759556055069 100 +5.539956212043762 100 +2.327750861644745 100 +6.608870148658752 100 +5.518165051937103 100 +4.606803238391876 100 +#HACK STRING EVAL +8.519548147916794 100 +3.2374559938907623 100 +8.346924066543579 100 +7.502279818058014 100 +9.521647661924362 100 +12.825910151004791 100 +10.209610223770142 10 +6.93452987074852 100 +10.84190958738327 100 +5.275553941726685 100 +#HACK STRING EVAL +8.87065726518631 100 +9.010664939880371 100 +11.147336393594742 100 +7.428218424320221 100 +2.9712496995925903 100 +8.160993874073029 100 +8.831124544143677 100 +5.127241015434265 100 +3.1628018617630005 100 +5.932207107543945 100 +#HACK STRING EVAL +5.232300758361816 4 +12.791633903980255 100 +9.728413939476013 100 +6.738530278205872 100 +11.016217470169067 100 +3.9511409997940063 100 +0.6138439178466797 100 +5.429259717464447 100 +11.513810813426971 100 +9.619035422801971 100 +#HACK STRING EVAL +5.816870152950287 100 +10.012716352939606 100 +10.794143468141556 100 +3.865249276161194 100 +11.84551626443863 100 +2.537244439125061 100 +9.099927008152008 100 +5.764299929141998 5 +8.805252015590668 100 +8.438510775566101 100 +#HACK STRING EVAL +10.670760184526443 100 +9.623911917209625 100 +10.761460363864899 100 +5.085796654224396 100 +8.62084823846817 100 +8.93079924583435 100 +8.334770262241364 100 +10.665028095245361 9 +5.183526456356049 100 +7.597260296344757 100 +#HACK STRING EVAL +8.018654972314835 100 +2.748644471168518 100 +11.547940611839294 100 +3.987261712551117 100 +7.838536262512207 100 +8.388153851032257 100 +8.628331124782562 100 +9.339502692222595 100 +7.5155910551548 100 +11.939184248447418 100 +#HACK STRING EVAL +3.7544268369674683 100 +5.978183925151825 100 +10.896731317043304 100 +7.859004974365234 100 +5.086252152919769 100 +12.971299231052399 100 +0.24850338697433472 100 +9.588801771402359 100 +1.2074859142303467 100 +7.202005743980408 100 +#HACK STRING EVAL +6.057201504707336 100 +4.030258804559708 100 +9.944912612438202 100 +7.819860816001892 100 +8.772306084632874 100 +6.95832085609436 100 +7.86069929599762 100 +8.707296371459961 100 +1.9138692021369934 100 +7.955980062484741 100 +#HACK STRING EVAL +4.909231245517731 100 +9.515767931938171 100 +8.852968454360962 100 +4.100440293550491 100 +8.853616952896118 100 +8.913927555084229 100 +8.692068696022034 100 +6.324617028236389 100 +4.746747314929962 100 +9.663675606250763 100 +#HACK STRING EVAL +4.567979097366333 100 +7.513888746500015 100 +7.33759206533432 100 +10.928641080856323 100 +6.088316202163696 100 +7.648386001586914 100 +6.254184514284134 100 +8.21787440776825 100 +7.338970065116882 100 +3.9549885988235474 100 +#HACK STRING EVAL +9.742068231105804 100 +-5.800307273864746 100 +5.903411000967026 98 +-4.080223083496094 100 +-5.476092338562012 100 +-3.6582727432250977 100 +-7.405650615692139 100 +-2.134929656982422 100 +8.017919182777405 100 +-4.270915985107422 100 +#HACK STRING EVAL +6.382547304034233 8 +5.2740448564291 7 +8.291682362556458 9 +10.547998368740082 10 +5.943011045455933 6 +10.214801788330078 11 +9.571770012378693 11 +8.963552176952362 10 +7.881802827119827 10 +9.55726170539856 10 +#HACK STRING EVAL +9.76809686422348 10 +8.597537100315094 7 +8.151359140872955 8 +4.947125032544136 7 +7.549626961350441 9 +11.071455359458923 9 +9.881853774189949 11 +7.5636414885520935 8 +5.990636169910431 7 +6.5525292456150055 100 +#HACK STRING EVAL +5.72771292924881 100 +7.8250386118888855 8 +4.282955527305603 4 +7.93784636259079 8 +10.406544864177704 100 +9.76392149925232 8 +6.965295135974884 100 +7.505255997180939 100 +10.074874997138977 8 +2.307618886232376 100 +#HACK STRING EVAL +6.608579993247986 100 +5.589818775653839 100 +8.721212148666382 7 +1.1971131563186646 1 +8.256390452384949 100 +5.6077892780303955 100 +4.1048919558525085 100 +8.040016293525696 6 +7.581324934959412 100 +1.6247807145118713 100 +#HACK STRING EVAL +7.464324116706848 100 +3.207527309656143 100 +9.424065470695496 100 +5.8272665143013 100 +10.650640487670898 100 +7.588376998901367 100 +10.114213526248932 100 +7.237074375152588 8 +1.6532004177570343 100 +5.680019676685333 100 +#HACK STRING EVAL +4.772526025772095 100 +5.27666974067688 100 +8.400729417800903 100 +10.621524095535278 100 +12.323681116104126 100 +2.0804484486579895 100 +12.284129530191422 100 +8.86272245645523 100 +8.18984842300415 100 +5.591330409049988 6 +#HACK STRING EVAL +6.030032217502594 100 +3.6866373121738434 100 +2.59875226020813 100 +3.5437865257263184 100 +8.711644947528839 100 +6.986307442188263 100 +7.056451499462128 6 +11.32332694530487 9 +8.744847416877747 100 +8.852237820625305 100 +#HACK STRING EVAL +8.021300375461578 100 +8.009023904800415 100 +5.567540943622589 100 +1.4400359988212585 100 +7.805281043052673 100 +5.297640681266785 100 +2.104386806488037 100 +6.8105632066726685 100 +5.27584969997406 100 +4.842580854892731 100 +#HACK STRING EVAL +8.719617247581482 100 +3.091191053390503 100 +8.202818870544434 100 +7.47697639465332 100 +9.72183084487915 100 +12.681255877017975 100 +9.63052898645401 100 +6.724223077297211 100 +10.63168078660965 100 +5.409387052059174 100 +#HACK STRING EVAL +8.893034636974335 100 +9.11386787891388 100 +11.182800829410553 100 +7.607516586780548 100 +3.07454913854599 100 +8.172030448913574 100 +8.86316329240799 100 +5.088163197040558 100 +3.197674125432968 100 +5.842472434043884 100 +#HACK STRING EVAL +5.176666855812073 4 +12.933996766805649 100 +9.870842784643173 100 +6.777136385440826 100 +10.870980381965637 100 +3.806485176086426 100 +0.6474044322967529 100 +5.4726263880729675 100 +11.49931013584137 100 +9.575879991054535 100 +#HACK STRING EVAL +6.051537990570068 100 +10.124665021896362 100 +10.809352278709412 100 +3.95347598195076 100 +11.707466423511505 100 +2.638509690761566 100 +9.22233259677887 100 +5.19345897436142 100 +8.718438029289246 100 +8.455293238162994 100 +#HACK STRING EVAL +10.554587244987488 100 +9.370258629322052 100 +10.776310324668884 100 +5.282650053501129 100 +8.567186117172241 100 +9.12459260225296 100 +8.302630245685577 100 +10.123352319002151 100 +5.2121418714523315 100 +7.566948711872101 100 +#HACK STRING EVAL +7.71593850851059 100 +2.8992066979408264 100 +11.410901069641113 100 +4.176903009414673 100 +7.74624240398407 100 +8.510929465293884 100 +8.650461852550507 100 +9.078275799751282 100 +7.340410888195038 100 +12.130875051021576 100 +#HACK STRING EVAL +3.824996054172516 100 +5.929306209087372 100 +10.825126886367798 100 +7.940617740154266 100 +5.190859705209732 100 +12.969503164291382 100 +0.22007757425308228 100 +9.53267115354538 100 +1.145200490951538 100 +7.180809020996094 100 +#HACK STRING EVAL +6.262947916984558 100 +3.816492795944214 100 +10.1120066344738 100 +8.09740063548088 100 +9.223297595977783 93 +6.971723556518555 100 +7.836474895477295 100 +9.219971030950546 65 +2.116775631904602 100 +7.621903359889984 100 +#HACK STRING EVAL +4.719651818275452 100 +9.269598960876465 100 +8.856775403022766 100 +4.073694795370102 100 +8.89053201675415 100 +8.878904044628143 100 +8.478850245475769 100 +6.099657088518143 100 +4.522204488515854 100 +9.623538970947266 100 +#HACK STRING EVAL +3.965794801712036 100 +7.913584232330322 100 +7.3617512583732605 100 +10.7222321331501 100 +6.6994858384132385 100 +8.01834362745285 100 +6.643414914608002 100 +8.441223382949829 100 +7.718792527914047 100 +3.9947091937065125 100 +#HACK STRING EVAL +-3.7503671646118164 100 +6.917860984802246 100 +-7.995953559875488 100 +-0.8005466461181641 100 +-6.310798645019531 100 +-4.496591567993164 100 +-9.295823574066162 100 +-1.0088205337524414 100 +-5.535251617431641 100 +-3.1447973251342773 100 +#HACK STRING EVAL +6.314683884382248 15 +5.171254143118858 11 +8.386786103248596 10 +10.552277311682701 17 +5.86377015709877 13 +10.06521451473236 11 +9.547597050666809 11 +8.944535464048386 11 +7.716569200158119 14 +9.491909176111221 17 +#HACK STRING EVAL +9.778729915618896 10 +8.600798487663269 8 +8.143956482410431 9 +4.939191594719887 6 +7.537592425942421 8 +11.081586301326752 9 +9.835757791996002 10 +7.5643031001091 8 +5.977133601903915 7 +6.83396315574646 7 +#HACK STRING EVAL +5.7507569789886475 100 +7.9980469942092896 8 +4.366934955120087 4 +7.920052587985992 8 +10.93835598230362 10 +9.824076175689697 8 +6.9830211997032166 100 +7.528299987316132 100 +10.01278531551361 8 +2.873948872089386 3 +#HACK STRING EVAL +6.457194209098816 100 +5.512147665023804 100 +8.745449006557465 7 +1.1901016235351562 1 +8.105004668235779 100 +5.710570871829987 100 +4.235429465770721 100 +7.982612252235413 6 +7.503653705120087 100 +1.473395049571991 100 +#HACK STRING EVAL +7.511815011501312 100 +3.0698293447494507 100 +9.380272060632706 100 +5.806468993425369 100 +10.75125503540039 100 +7.700076878070831 100 +10.07035744190216 100 +6.836740851402283 100 +1.753814935684204 100 +5.765758395195007 100 +#HACK STRING EVAL +4.659476935863495 100 +5.103555202484131 100 +8.366827696561813 100 +10.4483982026577 100 +12.150562345981598 100 +2.0635483264923096 100 +12.745144426822662 10 +8.888809442520142 100 +8.172989964485168 100 +5.141324758529663 100 +#HACK STRING EVAL +5.912182688713074 100 +3.8474230766296387 100 +2.5175044238567352 100 +3.365699529647827 100 +8.569548428058624 100 +7.067189455032349 100 +6.668564736843109 100 +11.420759320259094 9 +8.905717730522156 100 +8.952664017677307 100 +#HACK STRING EVAL +7.917258679866791 100 +8.163626968860626 100 +5.723752915859222 100 +1.594468206167221 100 +7.927509307861328 100 +5.4547231793403625 100 +2.2584047317504883 100 +6.66994571685791 100 +5.432999432086945 100 +4.664915323257446 100 +#HACK STRING EVAL +8.61397099494934 100 +3.132089376449585 100 +8.242016434669495 100 +7.607021272182465 100 +9.575037002563477 100 +12.720297276973724 100 +9.606988966464996 100 +6.825575947761536 100 +10.732893288135529 100 +5.380301296710968 100 +#HACK STRING EVAL +8.781927525997162 100 +8.873942494392395 100 +11.058974385261536 100 +7.367988288402557 100 +2.8350173234939575 100 +8.071952283382416 100 +8.742456793785095 100 +4.991371035575867 100 +3.0739530622959137 100 +5.84311842918396 100 +#HACK STRING EVAL +5.273882031440735 4 +12.762148141860962 100 +9.698699474334717 100 +6.821621060371399 100 +11.043958067893982 100 +3.9789161682128906 100 +0.6971036791801453 100 +5.435061395168304 100 +11.484049797058105 100 +9.556960940361023 100 +#HACK STRING EVAL +5.997173488140106 100 +10.057949662208557 100 +10.75470370054245 100 +3.9123013019561768 100 +11.792945384979248 100 +2.5830869376659393 100 +9.162891119718552 100 +5.785401880741119 5 +8.634621381759644 100 +8.39944064617157 100 +#HACK STRING EVAL +10.630252838134766 100 +9.506207406520844 100 +10.836455762386322 100 +5.104301542043686 100 +8.504844456911087 100 +9.042621850967407 100 +8.260082066059113 100 +10.084244728088379 100 +5.250549495220184 100 +7.621724545955658 100 +#HACK STRING EVAL +8.061362743377686 100 +2.6653700470924377 100 +11.557741701602936 100 +4.281035482883453 100 +8.132860720157623 100 +8.301540732383728 100 +8.546256393194199 100 +9.382239818572998 100 +7.233019948005676 100 +12.147982895374298 100 +#HACK STRING EVAL +4.187415957450867 100 +6.33720600605011 100 +10.833080559968948 100 +8.052283704280853 100 +4.736374080181122 100 +13.33787515759468 100 +-0.12588006258010864 100 +9.412563681602478 100 +1.0280697345733643 100 +7.290809154510498 100 +#HACK STRING EVAL +6.18980872631073 100 +3.750009059906006 100 +10.20350068807602 100 +7.391916811466217 100 +9.18588525056839 100 +7.35508394241333 100 +7.435403227806091 100 +8.73348331451416 100 +2.173562377691269 100 +8.37391984462738 100 +#HACK STRING EVAL +4.8031182289123535 100 +9.1607386469841 100 +9.611942082643509 42 +4.8554865419864655 76 +9.551824748516083 50 +9.219375938177109 100 +9.252277314662933 76 +6.888365745544434 78 +4.9394539296627045 69 +9.359731435775757 100 +#HACK STRING EVAL +3.981468975543976 100 +7.5596296191215515 100 +6.94868665933609 100 +10.580182075500488 100 +6.360088229179382 100 +7.69408905506134 100 +6.30370819568634 100 +8.693852245807648 100 +7.397533416748047 100 +3.897919774055481 100 +#HACK STRING EVAL +-3.7503671646118164 100 +-6.669588088989258 100 +-7.995953559875488 100 +-4.92095947265625 100 +-6.310798645019531 100 +-4.496591567993164 100 +-9.295823574066162 100 +-2.968735694885254 100 +-5.535251617431641 100 +-5.104723930358887 100 +#HACK STRING EVAL +6.391613692045212 17 +5.230714097619057 15 +8.238146930932999 21 +10.546338498592377 24 +5.872611358761787 19 +10.075507506728172 22 +9.344089388847351 22 +8.858555525541306 22 +7.709897920489311 23 +9.502225115895271 13 +#HACK STRING EVAL +9.593478202819824 100 +8.658819407224655 9 +8.271067678928375 9 +4.820446014404297 100 +7.422260761260986 100 +10.859588623046875 100 +9.999099612236023 11 +7.746126115322113 9 +5.965736627578735 7 +6.834715306758881 7 +#HACK STRING EVAL +6.129940450191498 7 +7.836400806903839 8 +4.427526026964188 5 +7.775103747844696 9 +10.987845778465271 10 +9.718576967716217 8 +7.36268150806427 8 +7.854459226131439 9 +10.102898716926575 8 +2.6835078597068787 3 +#HACK STRING EVAL +6.697846859693527 100 +5.964300572872162 6 +8.735662639141083 7 +1.1743757724761963 1 +8.345657110214233 100 +6.250426292419434 5 +4.358271092176437 100 +7.94635571539402 7 +7.992802441120148 7 +1.9118272066116333 2 +#HACK STRING EVAL +7.669235825538635 100 +3.15950471162796 100 +9.377454102039337 100 +6.305031657218933 6 +10.855552315711975 100 +7.663079708814621 100 +10.602166831493378 10 +6.941038370132446 100 +1.8697081506252289 100 +5.72876113653183 100 +#HACK STRING EVAL +4.684390366077423 100 +5.611595630645752 6 +8.451849281787872 100 +10.453387141227722 100 +12.23554539680481 100 +2.1703144311904907 100 +12.895542740821838 10 +9.373756110668182 9 +8.74528956413269 8 +5.59876811504364 6 +#HACK STRING EVAL +6.32160884141922 6 +3.7847110629081726 100 +2.5795997381210327 100 +3.290479600429535 100 +8.691700339317322 100 +7.150066614151001 100 +7.153164446353912 6 +11.046191185712814 100 +8.709838271141052 100 +9.477504193782806 10 +#HACK STRING EVAL +7.875272691249847 100 +8.317034125328064 100 +5.709950864315033 100 +1.7477060556411743 100 +7.793524205684662 100 +5.412659049034119 100 +2.411730647087097 100 +6.662802636623383 100 +5.390867114067078 100 +4.735195577144623 100 +#HACK STRING EVAL +8.693780064582825 100 +3.282778948545456 100 +8.392249584197998 100 +7.466298758983612 100 +9.69587367773056 100 +12.870824933052063 100 +9.466231286525726 100 +6.7525652050971985 100 +11.211679518222809 9 +5.2393516302108765 100 +#HACK STRING EVAL +8.79471468925476 100 +9.139041125774384 100 +11.071326196193695 100 +7.352254748344421 100 +3.099617153406143 100 +8.084969758987427 100 +8.755131930112839 100 +4.975205183029175 100 +3.0868238508701324 100 +5.856152355670929 100 +#HACK STRING EVAL +5.27423632144928 4 +13.245966792106628 10 +9.866550594568253 100 +6.6989147663116455 100 +11.164247870445251 100 +3.803130865097046 100 +0.5748847424983978 100 +5.57735812664032 100 +11.652009844779968 100 +9.701864063739777 100 +#HACK STRING EVAL +6.047025889158249 100 +9.930347204208374 100 +10.80030009150505 100 +3.8484577536582947 100 +11.937007367610931 100 +2.4584649205207825 100 +9.086014091968536 100 +5.825842261314392 5 +8.504900991916656 100 +8.444956660270691 100 +#HACK STRING EVAL +10.76778855919838 100 +9.64465257525444 100 +10.562536835670471 100 +5.043010652065277 100 +8.817883014678955 100 +8.887007385492325 100 +8.53173154592514 100 +10.06323191523552 100 +4.984281897544861 100 +7.321408152580261 100 +#HACK STRING EVAL +7.934100687503815 100 +3.0487946271896362 100 +11.256348133087158 100 +4.0361058712005615 100 +7.724862098693848 100 +8.24852168560028 100 +8.92816737294197 100 +9.066977441310883 100 +7.643976300954819 100 +12.55964207649231 10 +#HACK STRING EVAL +3.6748498678207397 100 +5.794861137866974 100 +10.813584357500076 100 +7.774772107601166 100 +5.2243015468120575 100 +13.489577889442444 10 +0.4375060200691223 100 +9.687025934457779 100 +1.3031297028064728 100 +7.0145129561424255 100 +#HACK STRING EVAL +5.930427402257919 100 +4.167952656745911 100 +10.04518723487854 100 +7.893225610256195 100 +8.478995501995087 100 +6.886724770069122 100 +8.199176967144012 100 +8.857572495937347 100 +2.0666070878505707 100 +7.657126009464264 100 +#HACK STRING EVAL +4.926782608032227 100 +9.026285946369171 100 +8.899517238140106 100 +4.144956111907959 100 +8.838810384273529 100 +8.965755224227905 100 +8.540810883045197 100 +6.173325628042221 100 +4.669879674911499 100 +9.636246860027313 100 +#HACK STRING EVAL +4.209121525287628 100 +7.251917600631714 100 +7.38650244474411 100 +11.02028602361679 100 +6.519894659519196 100 +7.678215801715851 100 +6.783213794231415 100 +8.647479802370071 100 +7.381934762001038 100 +3.9192428588867188 100 +#HACK STRING EVAL +-3.7503671646118164 100 +-6.669588088989258 100 +-7.995953559875488 100 +-4.92095947265625 100 +-6.310798645019531 100 +-4.496591567993164 100 +4.622463971376419 11 +-2.968735694885254 100 +-5.535251617431641 100 +-5.104723930358887 100 +#HACK STRING EVAL +6.303241401910782 11 +5.252747520804405 11 +8.259800225496292 15 +10.68131399154663 11 +6.08250817656517 7 +10.08971618115902 19 +9.369557529687881 16 +8.851862400770187 15 +7.812299698591232 10 +9.528980195522308 10 +#HACK STRING EVAL +9.69513800740242 12 +8.641425728797913 7 +8.114037871360779 8 +4.922669470310211 7 +7.583594396710396 9 +11.03451943397522 11 +9.902495086193085 10 +7.64936375617981 8 +6.035667181015015 7 +6.811473459005356 7 +#HACK STRING EVAL +5.818421930074692 100 +7.415058135986328 100 +4.349563300609589 5 +7.794465512037277 9 +10.818395495414734 10 +9.456449151039124 100 +7.056004166603088 100 +7.934576719999313 10 +10.075671672821045 8 +2.398327946662903 100 +#HACK STRING EVAL +6.37988543510437 100 +5.671456456184387 100 +8.84032028913498 7 +1.1220341920852661 1 +8.027695924043655 100 +6.20349246263504 5 +4.040309458971024 100 +7.615017473697662 100 +7.66296261548996 100 +1.3960862457752228 100 +#HACK STRING EVAL +7.711938053369522 100 +3.239923119544983 100 +9.218695402145386 100 +5.6217986941337585 100 +10.898254603147507 100 +8.213463544845581 8 +10.48999959230423 10 +6.9837407767772675 100 +1.9008144736289978 100 +5.570002734661102 100 +#HACK STRING EVAL +4.361894309520721 100 +5.418456256389618 100 +8.129353612661362 100 +10.210892528295517 100 +11.913049459457397 100 +2.3637813925743103 100 +12.745551943778992 10 +9.420785307884216 9 +7.920804858207703 100 +5.441558212041855 100 +#HACK STRING EVAL +6.139715135097504 100 +3.8575188517570496 100 +2.2721581161022186 100 +3.18048495054245 100 +9.129072606563568 10 +7.31561154127121 100 +6.835742086172104 100 +10.647692412137985 100 +8.599850296974182 100 +9.180222541093826 100 +#HACK STRING EVAL +7.592684686183929 100 +8.456152498722076 100 +5.783128440380096 100 +1.8868265748023987 100 +7.637711197137833 100 +5.485836565494537 100 +2.5508499443531036 100 +6.380217105150223 100 +5.464044749736786 100 +4.726276397705078 100 +#HACK STRING EVAL +8.226992011070251 100 +3.4545333981513977 100 +8.564038395881653 100 +7.941070169210434 100 +9.897475928068161 100 +13.04260540008545 100 +9.940962672233582 100 +6.519895702600479 100 +10.85842102766037 100 +5.374180823564529 100 +#HACK STRING EVAL +8.54410058259964 100 +8.999019742012024 100 +11.224535763263702 100 +7.10175758600235 100 +2.9595972299575806 100 +7.834116697311401 100 +8.504512310028076 100 +4.724259078502655 100 +2.8358942568302155 100 +6.332024335861206 100 +#HACK STRING EVAL +5.264292597770691 4 +13.207925915718079 10 +9.630826741456985 100 +6.5933427810668945 100 +11.150360226631165 100 +4.085294008255005 100 +0.46736595034599304 100 +5.6748795211315155 100 +11.693776607513428 100 +9.794797539710999 100 +#HACK STRING EVAL +5.631375968456268 100 +9.82599750161171 100 +10.967703998088837 100 +3.6792758107185364 100 +12.028012156486511 100 +2.3502300083637238 100 +8.920581042766571 100 +5.608486592769623 100 +8.402168452739716 100 +8.031251281499863 100 +#HACK STRING EVAL +10.290916442871094 100 +9.397692382335663 100 +10.385363459587097 100 +5.5271367728710175 100 +8.78556913137436 100 +8.776054441928864 100 +8.698202669620514 100 +10.546246767044067 100 +4.811224162578583 100 +7.370879411697388 100 +#HACK STRING EVAL +8.116089522838593 100 +3.079993963241577 100 +11.168271124362946 100 +4.263869345188141 100 +8.115143537521362 100 +8.486479341983795 100 +8.73981088399887 100 +9.261997640132904 100 +7.700937420129776 100 +12.215804874897003 100 +#HACK STRING EVAL +3.9897977709770203 100 +6.451704621315002 65 +11.132048666477203 100 +8.094370782375336 100 +5.395056903362274 48 +13.44430822134018 53 +0.6055170893669128 70 +9.854711592197418 77 +1.0022233128547668 100 +7.3340984582901 100 +#HACK STRING EVAL +6.558522582054138 100 +3.6940096616744995 100 +10.284237146377563 100 +8.104119062423706 100 +8.484338700771332 100 +6.665755867958069 100 +8.156622171401978 100 +8.479896903038025 100 +2.253202736377716 100 +7.675540775060654 100 +#HACK STRING EVAL +4.582699120044708 100 +9.616458654403687 72 +9.609985649585724 69 +4.857894212007523 63 +9.551293075084686 89 +9.67571097612381 53 +9.029149383306503 100 +6.8863272070884705 63 +4.335278630256653 100 +9.746216535568237 72 +#HACK STRING EVAL +4.636946678161621 100 +7.244731545448303 100 +7.38682559132576 100 +10.218576282262802 100 +6.5996400117874146 100 +7.952930301427841 100 +6.776047170162201 100 +8.963248044252396 100 +7.642178297042847 100 +3.6699575185775757 100 +#HACK STRING EVAL +-3.7503671646118164 100 +-6.669588088989258 100 +-7.995953559875488 100 +-4.92095947265625 100 +-6.310798645019531 100 +-4.496591567993164 100 +-9.295823574066162 100 +-2.968735694885254 100 +-5.535251617431641 100 +-5.104723930358887 100 +#HACK STRING EVAL +6.307459145784378 13 +5.162187933921814 11 +8.413212209939957 13 +10.545510604977608 17 +5.860731720924377 13 +10.183098942041397 13 +9.475928902626038 14 +8.863045126199722 13 +7.874717712402344 10 +9.493808716535568 17 +#HACK STRING EVAL +9.696040585637093 11 +8.582586348056793 8 +8.204776838421822 10 +4.900086581707001 6 +7.508224472403526 8 +11.005810916423798 9 +9.922903060913086 10 +7.649450302124023 8 +6.020630121231079 7 +6.899221867322922 8 +#HACK STRING EVAL +5.632567405700684 100 +7.936746776103973 8 +4.4014932513237 4 +7.772646844387054 8 +10.554018139839172 100 +9.4493008852005 100 +7.048855900764465 100 +7.85152131319046 8 +10.026198267936707 8 +2.8246419429779053 3 +#HACK STRING EVAL +6.498895823955536 100 +5.432187259197235 100 +8.678643703460693 7 +1.158502221107483 1 +8.146706402301788 100 +5.703157007694244 100 +4.162100791931152 100 +7.984817743301392 6 +7.934486925601959 7 +1.5150966048240662 100 +#HACK STRING EVAL +7.569443225860596 100 +3.0718022882938385 100 +9.382245004177094 100 +5.682080835103989 100 +10.755759716033936 100 +7.6934961676597595 100 +10.072330713272095 100 +6.841245532035828 100 +1.7583195567131042 100 +5.826268017292023 100 +#HACK STRING EVAL +4.623560309410095 100 +5.3121357858181 100 +8.391019225120544 100 +10.65698978304863 100 +12.174715340137482 100 +1.9015889763832092 100 +12.321371614933014 100 +9.03731307387352 100 +8.011053383350372 100 +4.9793417155742645 100 +#HACK STRING EVAL +5.942218780517578 100 +3.750158280134201 100 +2.6882342398166656 100 +3.4559304118156433 100 +8.800342589616776 100 +6.896776735782623 100 +7.096493363380432 6 +10.701834738254547 100 +8.875329852104187 100 +9.486529111862183 10 +#HACK STRING EVAL +7.9460867047309875 100 +8.109675645828247 100 +5.670185089111328 100 +1.5414324402809143 100 +7.990170478820801 100 +5.366644263267517 100 +2.2043084502220154 100 +6.733596622943878 100 +5.344999611377716 100 +4.744504928588867 100 +#HACK STRING EVAL +8.635407447814941 100 +2.9695823192596436 100 +8.080438375473022 100 +7.5423256158828735 100 +9.63613873720169 100 +12.559446305036545 100 +9.77247816324234 100 +7.019331276416779 100 +10.696694552898407 100 +5.454880774021149 100 +#HACK STRING EVAL +9.114918410778046 100 +8.959027230739594 100 +11.391923755407333 100 +7.449903428554535 100 +2.9210851788520813 100 +8.405693262815475 100 +9.075240164995193 100 +5.295830518007278 100 +3.407511740922928 100 +6.177014470100403 100 +#HACK STRING EVAL +4.981851279735565 100 +12.69681590795517 100 +9.631421089172363 100 +7.053638279438019 100 +11.10530698299408 100 +4.042028307914734 100 +0.9134435057640076 100 +5.230226397514343 100 +11.416565954685211 100 +9.33784157037735 100 +#HACK STRING EVAL +5.900676846504211 100 +10.187435567378998 100 +10.658405423164368 100 +4.044117987155914 100 +11.657367587089539 100 +2.714713931083679 100 +9.235166311264038 100 +5.845587313175201 5 +8.804117321968079 100 +8.298364639282227 100 +#HACK STRING EVAL +10.661418497562408 100 +9.387579321861267 100 +10.662634074687958 100 +5.292759090662003 100 +8.704307615756989 100 +9.163248300552368 100 +8.416085243225098 100 +10.266054570674896 100 +5.084313631057739 100 +7.420696973800659 100 +#HACK STRING EVAL +8.279966861009598 100 +2.4426217079162598 100 +11.861989200115204 100 +4.050549149513245 100 +7.779791533946991 100 +8.268948554992676 100 +8.314508080482483 100 +9.593091398477554 100 +7.45445454120636 100 +12.428335011005402 100 +#HACK STRING EVAL +3.820194721221924 100 +6.397172510623932 100 +11.15693974494934 100 +8.04232370853424 100 +4.734496593475342 100 +13.378388911485672 100 +-0.15814048051834106 100 +9.540654003620148 100 +1.0576329827308655 100 +7.56172102689743 100 +#HACK STRING EVAL +6.641790479421616 100 +4.080964982509613 100 +9.813416123390198 100 +7.402722597122192 100 +9.185066163539886 100 +7.368130654096603 100 +7.45303738117218 100 +8.40563389658928 100 +1.782145768404007 100 +8.36425632238388 100 +#HACK STRING EVAL +4.581028401851654 100 +9.232562482357025 100 +9.145760595798492 100 +4.390700876712799 100 +9.08672171831131 100 +9.212102353572845 100 +9.044392675161362 100 +6.6549912095069885 100 +4.472315430641174 100 +9.356100857257843 100 +#HACK STRING EVAL +4.023656100034714 100 +7.287517428398132 100 +6.631805121898651 100 +10.264688611030579 100 +6.069896996021271 100 +7.423421949148178 100 +6.258418321609497 100 +8.8341643512249 100 +7.1131947338581085 100 +4.111683160066605 100 +#HACK STRING EVAL +-1.5935707092285156 100 +-6.669588088989258 100 +-5.281586647033691 100 +-2.2066192626953125 100 +-6.310798645019531 100 +-1.7822504043579102 100 +-6.581422328948975 100 +-2.968735694885254 100 +-1.9054269790649414 100 +-5.104723930358887 100 +#HACK STRING EVAL +6.360089302062988 7 +5.030101180076599 100 +8.095066010951996 100 +10.628913521766663 11 +5.862162292003632 6 +9.926582306623459 100 +9.209073007106781 100 +8.714440286159515 100 +7.572734773159027 100 +9.540570437908173 9 +#HACK STRING EVAL +9.709549188613892 10 +8.7246253490448 7 +8.13759696483612 8 +4.82421213388443 100 +7.426020592451096 100 +11.058963775634766 9 +9.945681154727936 10 +7.690646588802338 8 +5.870119959115982 100 +6.567236840724945 100 +#HACK STRING EVAL +5.726919382810593 100 +7.97978150844574 8 +4.344977259635925 4 +7.779569387435913 8 +10.469663858413696 100 +9.759026885032654 8 +7.336753487586975 8 +7.50446230173111 100 +9.612392395734787 100 +2.792326271533966 3 +#HACK STRING EVAL +6.385015517473221 100 +5.682357013225555 100 +8.371970772743225 100 +1.174450397491455 1 +8.044002413749695 100 +5.752675116062164 100 +4.2116188406944275 100 +8.018460035324097 6 +7.673863053321838 100 +1.412393033504486 100 +#HACK STRING EVAL +7.691239237785339 100 +2.9972745180130005 100 +9.307717561721802 100 +6.324812889099121 6 +10.7947538793087 100 +7.522718548774719 100 +9.997803777456284 100 +6.9630416333675385 100 +1.5875420570373535 100 +5.588400185108185 100 +#HACK STRING EVAL +4.441951394081116 100 +5.040304720401764 100 +8.303630203008652 100 +10.385165363550186 100 +12.08732157945633 100 +2.2848604023456573 100 +12.488411694765091 100 +9.33921879529953 9 +8.39430022239685 100 +4.969202429056168 100 +#HACK STRING EVAL +5.842625170946121 100 +3.909256935119629 100 +2.4386056065559387 100 +3.2905112504959106 100 +8.546335279941559 100 +7.167975604534149 100 +6.730383515357971 100 +11.015304267406464 100 +8.769745171070099 100 +8.856432735919952 100 +#HACK STRING EVAL +7.672137796878815 100 +8.369106322526932 100 +5.90646767616272 100 +1.8149680495262146 100 +8.057826340198517 100 +5.55021995306015 100 +2.3822070360183716 100 +6.46947717666626 100 +5.594948261976242 100 +4.5527655482292175 100 +#HACK STRING EVAL +8.477824181318283 100 +3.0508673787117004 100 +8.322737514972687 100 +7.545411229133606 100 +9.494185090065002 100 +12.638345003128052 100 +9.554382562637329 100 +6.9348562359809875 100 +10.855743408203125 100 +5.297492504119873 100 +#HACK STRING EVAL +8.663269579410553 100 +8.745284676551819 100 +10.94116759300232 100 +7.209976434707642 100 +2.7052506804466248 100 +7.91518235206604 100 +8.628124356269836 100 +4.866007626056671 100 +2.959004819393158 100 +5.696335524320602 100 +#HACK STRING EVAL +5.186655759811401 4 +12.583592653274536 100 +9.497697234153748 100 +6.458987921476364 100 +11.192332029342651 100 +4.127501726150513 100 +0.32494810223579407 100 +5.613015294075012 100 +11.993325591087341 10 +9.85082882642746 100 +#HACK STRING EVAL +5.684624493122101 100 +10.532763838768005 99 +10.440523505210876 100 +4.13554322719574 100 +12.153114020824432 92 +3.0615294575691223 55 +9.372825115919113 100 +5.734875917434692 93 +9.107343435287476 95 +8.742395401000977 71 +#HACK STRING EVAL +10.565195083618164 100 +9.15907073020935 100 +10.698407530784607 100 +5.346622169017792 100 +8.69191288948059 100 +9.077265501022339 100 +8.397243738174438 100 +10.237178325653076 100 +5.121258199214935 100 +7.122201025485992 100 +#HACK STRING EVAL +8.131300002336502 100 +3.1329150795936584 100 +11.991996049880981 11 +4.277786314487457 100 +7.589358001947403 100 +8.77482944726944 100 +8.981550484895706 100 +8.940876603126526 100 +7.755693316459656 100 +12.231048345565796 100 +#HACK STRING EVAL +4.15752699971199 100 +5.681244134902954 100 +10.713857293128967 100 +8.268361449241638 100 +5.236833930015564 100 +12.665635645389557 100 +0.5990710854530334 100 +9.124390870332718 100 +0.7426728010177612 100 +7.50088170170784 100 +#HACK STRING EVAL +6.163763165473938 100 +3.7779764533042908 100 +9.914122939109802 100 +7.788910090923309 100 +8.768939018249512 100 +6.952390372753143 100 +7.618392288684845 100 +8.612143695354462 100 +2.2451956272125244 100 +7.942905366420746 100 +#HACK STRING EVAL +5.1074420511722565 100 +9.61877566576004 48 +9.612777054309845 61 +4.863138943910599 41 +9.471739113330841 100 +9.682132214307785 59 +8.510420888662338 100 +6.885725378990173 61 +4.860059440135956 100 +9.748058140277863 72 +#HACK STRING EVAL +4.498666942119598 100 +7.336632490158081 100 +7.403058290481567 28 +10.405231893062592 100 +6.521828651428223 100 +7.546567797660828 100 +6.796538293361664 46 +8.27183923125267 100 +7.332441926002502 100 +3.6849896907806396 100 +#HACK STRING EVAL +2.65023136138916 100 +1.0220694541931152 100 +0.6107296943664551 100 +1.1671686172485352 100 +-0.2708120346069336 100 +1.5443229675292969 100 +-1.9547085762023926 100 +2.9013023376464844 100 +0.8577489852905273 100 +2.451904296875 100 +#HACK STRING EVAL +6.008959770202637 100 +4.8695454597473145 100 +7.934510409832001 100 +10.245553970336914 100 +5.566291809082031 100 +9.766026496887207 100 +9.048517405986786 100 +8.55388468503952 100 +7.412178933620453 100 +9.196401596069336 100 +#HACK STRING EVAL +9.834399908781052 11 +8.644213646650314 8 +8.196990132331848 9 +5.075690686702728 6 +7.679847180843353 8 +11.121819615364075 9 +9.800501644611359 10 +7.57257479429245 8 +6.016848593950272 7 +6.8983771204948425 7 +#HACK STRING EVAL +5.816885471343994 100 +7.945018708705902 8 +4.379792392253876 4 +7.7099403738975525 8 +10.959514021873474 10 +9.78609323501587 8 +7.4270636439323425 8 +7.843690037727356 8 +10.027977466583252 8 +2.4734892547130585 100 +#HACK STRING EVAL +6.4995501935482025 100 +5.544469237327576 100 +8.771901190280914 7 +1.158869981765747 1 +8.147360920906067 100 +5.610685110092163 100 +4.0696287751197815 100 +7.959600567817688 6 +7.9776211977005005 7 +1.6778680086135864 100 +#HACK STRING EVAL +7.4853968024253845 100 +3.1918370127677917 100 +9.502279698848724 100 +6.314307451248169 6 +10.671713292598724 100 +7.609449803829193 100 +10.137416541576385 100 +6.7571991086006165 100 +1.6742730736732483 100 +5.7986385226249695 100 +#HACK STRING EVAL +4.700054347515106 100 +5.314230531454086 100 +8.57754573225975 100 +10.54905241727829 100 +12.361241847276688 100 +2.0185527205467224 100 +12.222103297710419 100 +8.744436115026474 100 +8.127994745969772 100 +5.0963292717933655 100 +#HACK STRING EVAL +5.9817987978458405 100 +3.687064051628113 100 +2.58720925450325 100 +3.545038938522339 100 +8.748811960220337 100 +7.004145085811615 100 +6.508184432983398 100 +10.793120205402374 100 +8.914906024932861 100 +9.022298693656921 100 +#HACK STRING EVAL +7.779959261417389 100 +8.17408674955368 100 +5.614638030529022 100 +1.6048362255096436 100 +7.824986219406128 100 +5.317346274852753 100 +2.268876314163208 100 +6.665189802646637 100 +5.295555353164673 100 +4.812402844429016 100 +#HACK STRING EVAL +8.684840977191925 100 +3.18524706363678 100 +8.295200824737549 100 +7.499653577804565 100 +9.686932623386383 100 +12.77385687828064 100 +9.552219331264496 100 +6.7469213008880615 100 +10.654320359230042 100 +5.50357848405838 100 +#HACK STRING EVAL +8.872677147388458 100 +9.068031787872314 100 +11.149329245090485 100 +7.562237441539764 100 +3.029275119304657 100 +8.162736356258392 100 +8.833036422729492 100 +5.05330753326416 100 +3.1098268032073975 100 +5.934210985898972 100 +#HACK STRING EVAL +5.206875443458557 4 +13.283404171466827 11 +9.713337004184723 100 +6.8416712284088135 100 +11.00681883096695 100 +3.9674946665763855 100 +0.715263158082962 100 +5.430297255516052 100 +11.438931822776794 100 +9.544408977031708 100 +#HACK STRING EVAL +5.822925806045532 100 +10.106406092643738 100 +10.580310821533203 100 +4.092210471630096 100 +11.635900139808655 100 +2.621044784784317 100 +9.329886674880981 100 +5.435180276632309 100 +8.593034505844116 100 +8.225131273269653 100 +#HACK STRING EVAL +10.405126988887787 100 +9.41513192653656 100 +10.49438726902008 100 +5.420526176691055 100 +8.877249032258987 100 +8.876823544502258 100 +8.592487663030624 100 +10.439422875642776 100 +4.915586471557617 100 +7.253677845001221 100 +#HACK STRING EVAL +8.039065927267075 100 +2.8599507808685303 100 +11.408540904521942 100 +4.186848878860474 100 +8.121629536151886 100 +8.489125609397888 100 +8.738908380270004 100 +9.225174605846405 100 +7.472085356712341 100 +12.13894909620285 100 +#HACK STRING EVAL +3.9109339714050293 100 +6.16690981388092 100 +11.189828336238861 100 +8.239434152841568 100 +4.870359301567078 100 +13.146288454532623 100 +0.07555997371673584 100 +9.430342048406601 100 +0.8400977253913879 100 +7.3789345026016235 100 +#HACK STRING EVAL +6.168466746807098 100 +3.7269163727760315 100 +10.228099405765533 100 +7.5880056619644165 100 +8.906258583068848 100 +7.160625725984573 100 +7.81646591424942 100 +8.953028082847595 100 +2.209103584289551 100 +7.995312809944153 100 +#HACK STRING EVAL +4.600261151790619 100 +9.3519167304039 100 +9.432409256696701 100 +4.414782106876373 100 +9.392580687999725 100 +9.217379450798035 100 +8.987751543521881 100 +6.701495796442032 100 +4.31501242518425 100 +9.152707189321518 100 +#HACK STRING EVAL +4.0316142141819 100 +7.786611199378967 100 +6.781920522451401 100 +10.80302107334137 100 +6.53383207321167 100 +7.920876443386078 100 +6.367887794971466 100 +8.392025470733643 100 +7.649105191230774 100 +3.62294340133667 100 +#HACK STRING EVAL +0.20676326751708984 100 +2.6639089584350586 100 +-3.779402732849121 100 +3.981318950653076 100 +-1.8758516311645508 100 +4.932228088378906 100 +-5.160813808441162 100 +6.651952266693115 100 +-1.3935422897338867 100 +5.167376518249512 100 +#HACK STRING EVAL +6.085858702659607 9 +5.058122098445892 8 +7.982554495334625 21 +10.331905782222748 16 +5.620618283748627 11 +9.857949078083038 25 +9.097768545150757 23 +8.645807027816772 23 +7.46203076839447 12 +9.288152754306793 14 +#HACK STRING EVAL +9.491069555282593 11 +8.505914568901062 7 +7.923822969198227 9 +4.666321396827698 6 +7.263673663139343 8 +10.901008427143097 10 +9.746647119522095 10 +7.479682683944702 8 +5.71474027633667 6 +6.49965500831604 7 +#HACK STRING EVAL +6.120825618505478 7 +7.887461066246033 8 +4.343820691108704 4 +7.672709286212921 8 +10.854669630527496 10 +9.774289608001709 8 +7.48026704788208 8 +7.745144248008728 8 +9.975023448467255 8 +2.776032865047455 3 +#HACK STRING EVAL +6.791788578033447 7 +5.896398812532425 6 +8.635754525661469 7 +1.2048875093460083 1 +8.428135007619858 8 +6.059396505355835 5 +4.416509658098221 5 +7.964335083961487 6 +7.955077111721039 7 +1.74417245388031 2 +#HACK STRING EVAL +7.773880809545517 8 +3.343857765197754 3 +9.741983324289322 9 +6.3276686668396 6 +10.911227881908417 10 +8.07536095380783 8 +10.61697667837143 10 +7.23452216386795 8 +2.116843819618225 2 +5.942163378000259 6 +#HACK STRING EVAL +4.889075517654419 5 +5.123793661594391 100 +8.721153736114502 7 +10.678516864776611 8 +12.170805037021637 100 +2.441106081008911 2 +12.645869553089142 10 +9.200331628322601 9 +8.488333702087402 8 +5.514398038387299 6 +#HACK STRING EVAL +6.101896405220032 6 +3.8783183097839355 100 +2.725083649158478 3 +3.776829957962036 4 +8.914152324199677 10 +7.311903238296509 8 +6.955484449863434 6 +11.331178545951843 9 +9.043197274208069 10 +9.227405607700348 10 +#HACK STRING EVAL +7.970439195632935 100 +8.336935639381409 8 +5.7725483775138855 100 +1.8558406233787537 2 +8.015464842319489 100 +5.507825434207916 100 +2.504864454269409 3 +6.674365937709808 100 +5.486033737659454 100 +4.63271164894104 100 +#HACK STRING EVAL +8.75621473789215 9 +3.172142803668976 100 +8.403166264295578 7 +7.803471267223358 8 +9.964170813560486 8 +12.76018911600113 100 +9.794196635484695 10 +6.951463341712952 100 +11.005991041660309 9 +5.36959046125412 100 +#HACK STRING EVAL +8.926127314567566 100 +8.837515532970428 100 +11.202728152275085 100 +7.483661532402039 100 +2.798093020915985 100 +8.37704885005951 7 +8.886539340019226 100 +5.276635766029358 5 +3.3799580931663513 4 +6.1220768094062805 100 +#HACK STRING EVAL +5.211206555366516 4 +13.174967050552368 10 +9.537695348262787 100 +6.786191284656525 100 +11.082861483097076 100 +4.135817646980286 100 +0.959105372428894 1 +5.642171263694763 6 +12.012762427330017 10 +9.62046766281128 100 +#HACK STRING EVAL +5.89994078874588 100 +10.094578564167023 100 +10.901184439659119 10 +3.9511093497276306 100 +12.074494421482086 10 +2.8387200832366943 3 +9.437722325325012 10 +5.788454473018646 5 +8.66918832063675 100 +8.203495979309082 100 +#HACK STRING EVAL +10.565518200397491 100 +9.337350189685822 100 +10.655606806278229 100 +5.459936738014221 6 +8.723327100276947 100 +9.239396214485168 10 +8.437155425548553 100 +10.455514192581177 10 +5.077400207519531 100 +7.414452135562897 100 +#HACK STRING EVAL +8.187973380088806 8 +2.781720459461212 100 +11.505810022354126 100 +4.308797776699066 100 +8.218673288822174 9 +8.53140515089035 100 +8.78473699092865 100 +9.191039085388184 100 +7.376897573471069 100 +12.347278416156769 11 +#HACK STRING EVAL +4.054563641548157 100 +6.011923909187317 100 +11.268440783023834 10 +8.159100115299225 100 +4.994634509086609 100 +13.390119552612305 10 +0.3869185447692871 1 +9.28968894481659 100 +0.9084089994430542 100 +7.460308909416199 8 +#HACK STRING EVAL +6.468815565109253 7 +3.7192625403404236 100 +10.333160698413849 9 +7.7001742124557495 100 +8.7610302567482 100 +7.044191539287567 100 +7.912035167217255 100 +8.99765157699585 9 +2.438445210456848 2 +7.939164221286774 100 +#HACK STRING EVAL +4.687048673629761 100 +9.160450220108032 100 +9.231022953987122 100 +4.476475536823273 100 +9.360066175460815 10 +9.29727292060852 100 +8.872302889823914 100 +6.50484699010849 100 +4.439668953418732 100 +9.28896278142929 100 +#HACK STRING EVAL +4.420314788818359 5 +7.671341180801392 100 +7.1481543481349945 6 +10.648470938205719 100 +6.453735113143921 100 +8.045934796333313 7 +6.562846481800079 6 +8.484009504318237 100 +7.497005999088287 100 +3.7655553221702576 100 +#HACK STRING EVAL +0.21241188049316406 100 +-2.7068090438842773 100 +-4.033174514770508 100 +-0.9581804275512695 100 +-2.348019599914551 100 +-0.5338125228881836 100 +-5.333044528961182 100 +0.9940433502197266 100 +-1.5724725723266602 100 +-1.1419448852539062 100 +#HACK STRING EVAL +6.127954840660095 7 +5.034177929162979 6 +8.260284781455994 11 +10.417806327342987 12 +5.83191391825676 7 +10.14616972208023 11 +9.259876132011414 12 +8.909044951200485 12 +7.635110974311829 11 +9.323467761278152 9 +#HACK STRING EVAL +9.490519046783447 10 +8.547694563865662 7 +8.282342195510864 9 +5.0594372153282166 6 +7.6640936732292175 8 +10.964576482772827 9 +9.878730237483978 11 +7.65687957406044 9 +6.077269613742828 7 +6.918909549713135 7 +#HACK STRING EVAL +6.165643155574799 7 +7.702888131141663 8 +4.342631697654724 4 +7.824008584022522 8 +10.719494014978409 10 +9.83677589893341 8 +7.345179080963135 8 +7.591875910758972 8 +9.986940145492554 8 +2.704601526260376 3 +#HACK STRING EVAL +6.711922824382782 7 +5.817591518163681 6 +8.750322222709656 7 +1.1984447240829468 1 +8.353407859802246 8 +6.03612494468689 5 +4.404247432947159 5 +8.019487977027893 6 +7.985856890678406 7 +1.81460303068161 2 +#HACK STRING EVAL +7.762459844350815 8 +3.2992215156555176 3 +9.812734305858612 9 +6.1665239334106445 6 +10.921708106994629 9 +7.990202307701111 8 +10.380459725856781 10 +7.189347147941589 8 +2.0305439233779907 2 +5.923005640506744 6 +#HACK STRING EVAL +4.85748827457428 5 +5.573791801929474 6 +8.68732863664627 7 +10.743296027183533 8 +12.394462376832962 10 +2.381619930267334 2 +12.590419054031372 10 +9.123904585838318 9 +8.499096155166626 8 +5.6375619769096375 6 +#HACK STRING EVAL +6.372696161270142 6 +3.7915921211242676 100 +2.4812171459198 100 +3.4671891927719116 100 +8.59331750869751 100 +7.1382423639297485 100 +7.0175861120224 6 +11.162338495254517 9 +9.255467295646667 10 +9.514357030391693 10 +#HACK STRING EVAL +7.8108508586883545 100 +8.34739288687706 8 +5.82342666387558 100 +1.8613073825836182 2 +7.937648832798004 100 +5.430009484291077 100 +2.485190600156784 4 +6.59838080406189 100 +5.40821760892868 100 +4.719015955924988 100 +#HACK STRING EVAL +8.776926398277283 9 +3.2674572467803955 100 +8.503025710582733 8 +7.816865801811218 9 +9.825847148895264 8 +12.855503559112549 100 +9.482002794742584 100 +6.89579564332962 100 +10.956103503704071 10 +5.255123198032379 100 +#HACK STRING EVAL +8.761751055717468 100 +8.96460223197937 100 +11.362277746200562 10 +7.656362533569336 8 +2.925179123878479 100 +8.372615277767181 7 +8.722164988517761 100 +5.275840997695923 5 +3.432159423828125 4 +5.982426285743713 100 +#HACK STRING EVAL +5.21687114238739 4 +13.07893419265747 10 +9.718013048171997 100 +6.981821060180664 19 +11.253858149051666 9 +3.9465803503990173 100 +0.9282288551330566 1 +5.625819385051727 14 +11.503403902053833 100 +9.750674843788147 9 +#HACK STRING EVAL +6.093325138092041 17 +10.288500607013702 17 +10.95228236913681 10 +4.191721469163895 5 +11.90246319770813 12 +2.821353703737259 7 +9.38498541712761 19 +5.695462942123413 5 +8.890970945358276 10 +8.501572072505951 17 +#HACK STRING EVAL +10.816273242235184 10 +9.399351716041565 100 +10.518863499164581 100 +5.570899963378906 6 +8.874581575393677 9 +9.264705121517181 10 +8.562035381793976 100 +10.454345256090164 10 +4.940713882446289 100 +7.740058124065399 8 +#HACK STRING EVAL +8.250517785549164 9 +2.918707102537155 22 +11.709000021219254 19 +4.02071225643158 100 +8.208702445030212 9 +8.617623567581177 9 +8.493344902992249 100 +9.590108186006546 9 +7.523960500955582 26 +11.973988831043243 100 +#HACK STRING EVAL +4.081603527069092 21 +6.306456565856934 6 +10.8933345079422 100 +7.853499591350555 100 +5.165690332651138 6 +13.334895968437195 10 +0.36134785413742065 1 +9.579740047454834 100 +1.1978405714035034 100 +7.430054813623428 41 +#HACK STRING EVAL +6.4331314265728 27 +3.7307629585266113 100 +10.215010464191437 100 +7.969285190105438 26 +9.0696981549263 9 +7.059613525867462 100 +7.92680424451828 100 +9.107726871967316 9 +2.4565778970718384 2 +8.152663499116898 19 +#HACK STRING EVAL +4.855271100997925 100 +9.44059932231903 10 +9.365172863006592 15 +4.617015331983566 19 +9.311424016952515 31 +9.528638333082199 10 +9.025101900100708 9 +6.6442979872226715 13 +4.882562279701233 6 +9.49948450922966 20 +#HACK STRING EVAL +4.440526753664017 10 +7.82322570681572 17 +7.168181121349335 6 +10.590775549411774 100 +6.398866415023804 100 +8.034934401512146 7 +6.363050639629364 100 +8.566639959812164 100 +7.650320529937744 7 +3.830273151397705 100 +#HACK STRING EVAL +0.3611440658569336 100 +-2.558076858520508 100 +-4.949563980102539 100 +-0.07533550262451172 100 +5.950950264930725 100 +0.8707523345947266 100 +-4.288785457611084 100 +10.720773875713348 26 +-1.4237403869628906 100 +8.590600997209549 24 +#HACK STRING EVAL +6.114913910627365 12 +4.929404467344284 10 +8.055950611829758 10 +10.299160361289978 10 +5.6845565140247345 10 +9.826124280691147 14 +9.146778553724289 11 +8.706696718931198 11 +7.729394257068634 9 +9.333037406206131 15 +#HACK STRING EVAL +9.72197836637497 11 +8.416295647621155 7 +8.027323544025421 8 +4.877857208251953 6 +7.488044410943985 8 +11.05162626504898 9 +9.978534042835236 10 +7.720938742160797 8 +5.83842796087265 6 +6.8282546401023865 7 +#HACK STRING EVAL +5.931227028369904 7 +7.912991404533386 8 +4.16132378578186 4 +7.724013149738312 8 +10.916723608970642 10 +9.80386596918106 8 +7.392969191074371 8 +7.72025740146637 8 +9.710793852806091 8 +2.7975792288780212 3 +#HACK STRING EVAL +6.804616928100586 7 +5.62186986207962 100 +8.683639883995056 7 +1.1488314867019653 1 +8.27640151977539 7 +5.950111508369446 5 +4.306034803390503 4 +7.995305061340332 6 +7.829081773757935 7 +1.6525780856609344 2 +#HACK STRING EVAL +7.915649116039276 8 +3.4809913635253906 3 +9.892886936664581 9 +6.257894396781921 6 +10.938974916934967 9 +8.069166660308838 8 +10.614505469799042 10 +7.21134078502655 8 +2.1439883708953857 2 +5.732657968997955 100 +#HACK STRING EVAL +4.911918640136719 5 +5.110647678375244 100 +8.662925839424133 7 +10.751917839050293 8 +12.157659113407135 100 +2.429811477661133 2 +12.78088504076004 10 +9.217098832130432 9 +8.425026416778564 8 +5.7661426067352295 6 +#HACK STRING EVAL +6.253824949264526 6 +3.8910768032073975 100 +2.687931537628174 3 +3.337649345397949 100 +8.60567969083786 100 +7.272652238607407 8 +7.090220212936401 6 +11.178739666938782 9 +9.045359343290329 10 +9.173558741807938 11 +#HACK STRING EVAL +7.929804503917694 100 +8.232644736766815 100 +5.792642056941986 100 +1.8549878001213074 2 +7.885862648487091 100 +5.467190980911255 100 +2.476852595806122 3 +6.717334032058716 100 +5.445398986339569 100 +4.6562140583992 100 +#HACK STRING EVAL +8.877973914146423 9 +3.1861363649368286 100 +8.295613288879395 100 +7.562869429588318 100 +9.553819477558136 100 +12.774186134338379 100 +9.813376277685165 10 +6.881359577178955 100 +10.788739264011383 100 +5.335921823978424 100 +#HACK STRING EVAL +8.783824145793915 100 +8.887745976448059 100 +11.060426354408264 100 +7.341358959674835 100 +2.8483229279518127 100 +8.375936895608902 7 +8.744236767292023 100 +5.318146646022797 5 +3.4479199647903442 4 +6.2803730964660645 7 +#HACK STRING EVAL +5.182891368865967 4 +13.065629363059998 10 +9.575568974018097 100 +6.660237073898315 100 +11.164873600006104 100 +4.080063045024872 100 +0.9641739726066589 1 +5.6831724643707275 6 +11.360964894294739 100 +9.702462017536163 100 +#HACK STRING EVAL +5.876660883426666 100 +9.974635481834412 100 +10.885002791881561 11 +4.008606851100922 100 +11.865563452243805 100 +2.8419259786605835 3 +9.542662739753723 10 +5.891916036605835 5 +8.54923814535141 100 +8.182434737682343 100 +#HACK STRING EVAL +10.542292296886444 100 +9.468039751052856 100 +10.629312634468079 100 +5.228527843952179 100 +8.723125636577606 100 +9.335059523582458 10 +8.435505747795105 100 +10.45408433675766 9 +5.056855618953705 100 +7.392460465431213 100 +#HACK STRING EVAL +8.25499415397644 8 +2.7393019795417786 100 +11.52921837568283 100 +4.134053528308868 100 +8.25694715976715 9 +8.356668889522552 100 +8.617996275424957 100 +9.34206748008728 100 +7.340912222862244 100 +12.086475610733032 100 +#HACK STRING EVAL +4.1211855709552765 5 +6.039727032184601 100 +11.366898119449615 10 +7.970129430294037 100 +4.9652780294418335 100 +13.41400682926178 10 +0.3632502555847168 1 +9.482573330402374 100 +1.0997390151023865 100 +7.2611430287361145 100 +#HACK STRING EVAL +6.43740302324295 7 +3.8257704377174377 100 +10.303062677383423 100 +8.076674342155457 9 +8.992364913225174 9 +7.158515214920044 8 +8.004680097103119 100 +8.972046256065369 9 +2.420803189277649 2 +8.155087560415268 13 +#HACK STRING EVAL +4.915781617164612 100 +9.051228702068329 100 +9.089267790317535 100 +4.585299015045166 100 +9.040816903114319 100 +9.439412772655487 9 +8.683866500854492 100 +6.358821511268616 100 +4.7174142599105835 5 +9.42051750421524 100 +#HACK STRING EVAL +4.428473949432373 5 +7.693514466285706 100 +7.180632412433624 6 +10.535036385059357 100 +6.450344741344452 100 +7.940103769302368 13 +6.574126750230789 7 +8.592837274074554 100 +7.447748005390167 100 +3.7657740116119385 100 +#HACK STRING EVAL +0.07935142517089844 100 +-2.839869499206543 100 +-4.166234970092773 100 +-1.0912408828735352 100 +-2.4810800552368164 100 +-0.6668729782104492 100 +-5.466104984283447 100 +0.8609828948974609 100 +-1.7055330276489258 100 +-1.2750053405761719 100 +#HACK STRING EVAL +6.066309332847595 12 +4.938523381948471 11 +7.987618774175644 12 +10.378014743328094 11 +5.643751114606857 11 +9.847189635038376 13 +9.237178444862366 15 +8.682818174362183 14 +7.653439372777939 12 +9.278191983699799 15 +#HACK STRING EVAL +9.609240531921387 10 +8.49480926990509 7 +8.078584134578705 9 +4.685550212860107 5 +7.280048847198486 7 +10.97505235671997 9 +9.835975587368011 11 +7.618149399757385 9 +5.963836133480072 7 +6.737556040287018 7 +#HACK STRING EVAL +6.054246604442596 7 +7.854629874229431 8 +4.192780077457428 4 +7.861830055713654 8 +10.894461810588837 10 +9.769005954265594 8 +7.3660025000572205 8 +7.671266674995422 8 +9.861518740653992 8 +2.8303810954093933 3 +#HACK STRING EVAL +6.790286064147949 7 +5.878905266523361 6 +8.671429872512817 7 +1.1603461503982544 1 +8.37414887547493 8 +6.128023147583008 5 +4.353233188390732 5 +7.943860173225403 6 +8.160713851451874 7 +1.7617330253124237 2 +#HACK STRING EVAL +7.7377937734127045 8 +3.480073034763336 3 +9.669793665409088 9 +6.3913885951042175 6 +10.95917558670044 9 +8.07205355167389 8 +10.611177861690521 10 +7.131671220064163 8 +2.012681007385254 2 +6.030514568090439 6 +#HACK STRING EVAL +4.96308308839798 5 +5.368444442749023 6 +8.577126622200012 7 +10.781701683998108 8 +12.474502205848694 10 +2.4537861347198486 2 +12.680352687835693 10 +9.40029489994049 9 +8.539011418819427 8 +5.666629374027252 6 +#HACK STRING EVAL +6.1818559765815735 6 +4.1670244336128235 4 +2.9210832118988037 3 +3.5920267701148987 4 +8.84687077999115 10 +7.060338199138641 100 +6.822679251432419 6 +11.197173714637756 9 +9.130157828330994 10 +9.144722700119019 10 +#HACK STRING EVAL +7.847338080406189 100 +8.580767631530762 8 +5.906092405319214 6 +1.83865687251091 2 +7.892363905906677 100 +5.396556317806244 100 +2.484955817461014 4 +6.957958281040192 7 +5.831857919692993 6 +4.738838970661163 100 +#HACK STRING EVAL +8.803065776824951 9 +3.157789170742035 100 +8.267259895801544 100 +7.591125905513763 100 +10.153838753700256 8 +12.745835602283478 100 +9.822597742080688 11 +6.844201028347015 100 +11.058137655258179 9 +5.787760496139526 6 +#HACK STRING EVAL +8.881220698356628 100 +9.028480231761932 100 +11.15782231092453 100 +7.695392489433289 8 +2.98908269405365 100 +8.171532988548279 100 +8.841633200645447 100 +5.145071864128113 100 +3.8135178685188293 4 +5.942720115184784 100 +#HACK STRING EVAL +5.211872816085815 4 +13.238605618476868 10 +9.894251644611359 9 +6.74136608839035 100 +11.253106117248535 9 +3.976622998714447 100 +0.9708072543144226 1 +5.810649037361145 6 +12.036993324756622 10 +9.791029632091522 9 +#HACK STRING EVAL +5.942961871623993 100 +10.020420730113983 100 +10.701113760471344 100 +3.87699431180954 100 +12.0939399600029 10 +2.855460047721863 3 +9.20397138595581 100 +5.310664057731628 100 +8.712201237678528 100 +8.575688362121582 9 +#HACK STRING EVAL +10.808890759944916 10 +9.498372673988342 100 +10.652462482452393 100 +5.786372542381287 6 +8.916154503822327 9 +9.383417546749115 10 +8.406610429286957 100 +10.236195385456085 100 +5.074883341789246 100 +7.627487361431122 8 +#HACK STRING EVAL +8.30430680513382 8 +2.9394532442092896 3 +11.6136075258255 100 +4.086054861545563 100 +8.225607573986053 10 +8.242405652999878 100 +8.49560958147049 100 +9.423348546028137 100 +7.4279625415802 100 +12.668181657791138 10 +#HACK STRING EVAL +3.8570544719696045 100 +5.979405879974365 100 +11.328658699989319 10 +7.924899756908417 100 +4.995793163776398 100 +13.416947484016418 10 +0.2042444348335266 100 +9.73761260509491 10 +1.167153775691986 100 +7.5573954582214355 8 +#HACK STRING EVAL +6.218981862068176 100 +3.7247155904769897 100 +10.258075177669525 100 +7.752960383892059 100 +9.069618821144104 9 +7.010245263576508 100 +7.806629419326782 100 +9.105643272399902 9 +2.40668785572052 2 +8.015107929706573 100 +#HACK STRING EVAL +4.79005753993988 100 +9.169013857841492 100 +9.192242860794067 100 +4.4374871253967285 100 +9.55092340707779 10 +9.666848301887512 9 +8.830830693244934 100 +6.46579521894455 100 +4.780848979949951 5 +9.600831627845764 8 +#HACK STRING EVAL +4.331418812274933 100 +7.763262510299683 100 +6.909357309341431 100 +10.546911835670471 100 +6.345279216766357 100 +8.009000301361084 7 +6.3062965869903564 100 +8.674514770507812 100 +7.392113506793976 100 +4.038929224014282 5 +#HACK STRING EVAL +9.894221842288971 82 +-6.669588088989258 100 +5.656404912471771 37 +-4.92095947265625 100 +-6.310798645019531 100 +-4.496591567993164 100 +-9.295823574066162 100 +-2.968735694885254 100 +8.112111508846283 71 +-5.104723930358887 100 +#HACK STRING EVAL +6.139400869607925 8 +4.992660313844681 7 +7.868160367012024 100 +10.179204106330872 100 +5.499941945075989 100 +9.699676632881165 100 +8.982167363166809 100 +8.487534642219543 100 +-6.18892765045166 100 +9.440329611301422 10 +#HACK STRING EVAL +9.516865104436874 11 +8.324759423732758 7 +8.269759774208069 9 +4.6958149671554565 6 +7.475528657436371 9 +10.771014988422394 10 +9.854985177516937 11 +7.618692517280579 9 +5.927423536777496 7 +6.7508185505867 7 +#HACK STRING EVAL +6.209096729755402 7 +7.7500903606414795 8 +4.223686099052429 4 +7.644227623939514 8 +10.962744772434235 10 +9.688361048698425 8 +7.464345574378967 8 +7.988364338874817 9 +10.042189717292786 8 +2.6779825687408447 3 +#HACK STRING EVAL +6.779198050498962 7 +5.927911251783371 6 +8.632262706756592 7 +1.1813898086547852 1 +8.51313042640686 8 +6.048705339431763 5 +4.4841421246528625 5 +7.8673529624938965 6 +8.134064793586731 7 +1.7658615410327911 2 +#HACK STRING EVAL +7.846627980470657 8 +3.40997576713562 3 +9.76178827881813 9 +6.202569842338562 6 +10.92071133852005 9 +8.050657749176025 8 +10.599768877029419 10 +7.235381752252579 8 +2.0872270464897156 2 +6.046091377735138 6 +#HACK STRING EVAL +4.852260649204254 5 +5.651541531085968 6 +8.713933825492859 7 +10.852385520935059 8 +12.44334352016449 10 +2.4386038780212402 2 +12.86839485168457 10 +9.395463228225708 9 +8.754667162895203 8 +5.80593466758728 6 +#HACK STRING EVAL +6.320597410202026 6 +4.00644713640213 4 +2.7430782318115234 3 +3.8520259857177734 4 +8.899177700281143 10 +7.511949956417084 8 +7.094476640224457 6 +11.218767404556274 9 +9.334243714809418 10 +9.553472936153412 10 +#HACK STRING EVAL +8.005392909049988 100 +8.206638514995575 100 +5.766635596752167 100 +1.8688215017318726 2 +7.940333068370819 100 +5.542779266834259 100 +2.4818868041038513 3 +6.957499086856842 7 +5.613670527935028 6 +4.626248061656952 100 +#HACK STRING EVAL +8.790058970451355 9 +3.388330817222595 3 +8.284615576267242 100 +7.862346857786179 8 +9.9768705368042 8 +12.893967986106873 10 +9.586922466754913 100 +6.960877954959869 100 +11.056470036506653 9 +5.674479603767395 6 +#HACK STRING EVAL +8.884696066379547 100 +8.90765106678009 100 +11.161296844482422 100 +7.681434631347656 8 +2.868228554725647 100 +8.421593755483627 7 +8.845108151435852 100 +5.337123453617096 5 +3.4603893756866455 4 +6.163575053215027 7 +#HACK STRING EVAL +5.283508658409119 4 +13.138390302658081 10 +9.930966943502426 9 +6.8374364376068115 100 +11.399688243865967 9 +4.073082149028778 100 +0.944277286529541 1 +5.668974816799164 6 +11.712586760520935 10 +9.776492238044739 9 +#HACK STRING EVAL +5.895810306072235 100 +10.358507990837097 8 +10.915207266807556 11 +4.158000618219376 6 +11.695757985115051 100 +2.8221001625061035 3 +9.271747171878815 100 +5.378409922122955 100 +8.665057837963104 100 +8.29832410812378 100 +#HACK STRING EVAL +10.814414113759995 10 +9.63968226313591 33 +10.697897493839264 100 +5.216588318347931 100 +8.861226916313171 9 +9.304624378681183 10 +8.391865670681 100 +10.468256890773773 9 +5.119699597358704 100 +7.456780970096588 100 +#HACK STRING EVAL +8.252621829509735 8 +2.6718544363975525 100 +11.630109965801239 100 +4.267786145210266 100 +8.17735555768013 9 +8.579716742038727 9 +8.808975577354431 9 +9.440708458423615 100 +7.267043471336365 100 +12.394403010606766 10 +#HACK STRING EVAL +4.043381571769714 100 +6.3180912137031555 6 +11.185615479946136 100 +8.147915720939636 100 +4.831987023353577 100 +13.21996283531189 10 +0.38503333926200867 1 +9.63760095834732 10 +0.9414389133453369 100 +7.387634694576263 100 +#HACK STRING EVAL +6.614320635795593 7 +3.686200797557831 100 +10.283620655536652 100 +7.667101681232452 100 +8.673055648803711 100 +7.1531736850738525 28 +8.055962234735489 9 +8.670005440711975 100 +2.427983045578003 2 +8.152051895856857 26 +#HACK STRING EVAL +4.616386234760284 100 +9.380376428365707 25 +9.360664248466492 20 +4.615656465291977 22 +8.980701565742493 100 +9.587005198001862 10 +9.029744505882263 9 +6.779708564281464 6 +4.7846187353134155 5 +9.494460850954056 17 +#HACK STRING EVAL +4.4540159702301025 5 +7.811811745166779 16 +7.169929385185242 6 +10.781680673360825 34 +6.672192335128784 6 +7.940419554710388 38 +6.545377731323242 18 +8.731668323278427 12 +7.631826400756836 32 +4.004571467638016 23 +#HACK STRING EVAL +-3.7503671646118164 100 +-6.669588088989258 100 +-7.995953559875488 100 +-4.92095947265625 100 +-6.310798645019531 100 +-4.496591567993164 100 +-9.295823574066162 100 +-2.968735694885254 100 +-5.535251617431641 100 +-5.104723930358887 100 +#HACK STRING EVAL +6.09099605679512 11 +5.000475347042084 10 +8.060649901628494 14 +10.300759613513947 12 +5.6193093955516815 11 +9.875274509191513 12 +9.242624133825302 16 +8.66731470823288 15 +7.612508833408356 18 +9.26302394270897 15 +#HACK STRING EVAL +9.65798544883728 10 +8.529263615608215 7 +8.042030215263367 9 +4.722194135189056 5 +7.318135380744934 7 +11.127600252628326 9 +10.01007154583931 11 +7.7797200083732605 9 +6.134595632553101 7 +6.6484256982803345 7 +#HACK STRING EVAL +6.135559618473053 7 +7.805879652500153 8 +4.28469854593277 4 +7.822889924049377 8 +10.873562067747116 10 +9.784544944763184 8 +7.384590148925781 8 +7.629130840301514 8 +9.866775870323181 8 +2.771574318408966 3 +#HACK STRING EVAL +6.762482702732086 7 +5.8619135320186615 6 +8.515790581703186 7 +1.1594924926757812 1 +8.426266491413116 8 +6.141925632953644 5 +4.300375521183014 4 +7.989979386329651 6 +7.962920069694519 7 +1.757516324520111 2 +#HACK STRING EVAL +7.914582937955856 8 +3.382493019104004 3 +9.861505031585693 9 +6.307538688182831 6 +11.008689045906067 9 +7.9854313135147095 8 +10.642638802528381 10 +7.215957134962082 8 +2.1220176219940186 2 +5.8008429408073425 100 +#HACK STRING EVAL +4.910547614097595 5 +5.532258152961731 6 +8.711221277713776 7 +10.691893339157104 8 +12.398297488689423 10 +2.455584764480591 2 +12.70643162727356 10 +9.524675369262695 9 +8.413443922996521 8 +5.799502372741699 6 +#HACK STRING EVAL +6.31810849905014 6 +3.851259469985962 100 +2.7796430587768555 3 +3.939126491546631 4 +8.988585531711578 10 +7.300127953290939 8 +7.14456707239151 6 +11.273043990135193 9 +8.909469783306122 100 +9.260104060173035 10 +#HACK STRING EVAL +8.182866275310516 9 +8.433194279670715 8 +5.820774674415588 100 +1.9023805856704712 2 +7.968813240528107 100 +5.461173832416534 100 +2.474765956401825 4 +6.651183128356934 100 +5.439381659030914 100 +4.710763216018677 100 +#HACK STRING EVAL +8.79382610321045 9 +3.299609899520874 3 +8.482496201992035 8 +7.8060882687568665 9 +9.860704064369202 8 +12.878999829292297 20 +9.82405498623848 10 +6.860293030738831 100 +11.147154211997986 9 +5.758793473243713 6 +#HACK STRING EVAL +8.812012374401093 100 +9.053521811962128 100 +11.351568639278412 10 +7.665497392416 9 +3.0140992999076843 100 +8.372685849666595 7 +8.772424340248108 100 +5.3125845193862915 5 +3.5707181096076965 4 +6.17053946852684 7 +#HACK STRING EVAL +5.221644043922424 4 +13.04363203048706 10 +9.662911057472229 100 +6.975515991449356 13 +11.100595355033875 100 +4.035528838634491 100 +0.9789295792579651 1 +5.513641536235809 100 +11.73605990409851 11 +9.825972557067871 9 +#HACK STRING EVAL +6.094496011734009 6 +10.293969511985779 15 +10.85883116722107 10 +4.191918611526489 5 +11.912913590669632 10 +2.9056426286697388 3 +9.424181461334229 10 +5.83813613653183 5 +8.86406746506691 17 +8.34725296497345 100 +#HACK STRING EVAL +10.879378139972687 9 +9.56550908088684 100 +10.874424815177917 11 +5.564581513404846 6 +8.871725171804428 22 +9.257323652505875 17 +8.578276813030243 16 +10.684615969657898 9 +5.279887765645981 15 +7.631276726722717 19 +#HACK STRING EVAL +8.217864245176315 9 +2.926612466573715 18 +11.714042693376541 19 +4.159390568733215 100 +8.011083781719208 100 +8.38084489107132 100 +8.634391903877258 100 +9.520875841379166 15 +7.352199375629425 100 +12.41771712899208 11 +#HACK STRING EVAL +3.9153279066085815 100 +6.217438340187073 23 +11.341838479042053 10 +8.024797916412354 100 +5.1510105431079865 10 +13.210659265518188 27 +0.36558011174201965 20 +9.616865694522858 18 +1.0654784440994263 100 +7.263701796531677 100 +#HACK STRING EVAL +6.5703370571136475 7 +3.9910643100738525 30 +10.318411588668823 9 +7.794466733932495 100 +8.977440536022186 25 +6.9977747797966 100 +8.040332108736038 9 +8.973136693239212 23 +2.4381892681121826 2 +8.156003534793854 31 +#HACK STRING EVAL +4.639429867267609 100 +9.367762058973312 30 +9.362144589424133 7 +4.6064035296440125 19 +9.424470067024231 10 +9.545778632164001 9 +9.02881920337677 9 +6.753341376781464 6 +4.722804844379425 6 +9.499340415000916 18 +#HACK STRING EVAL +4.434442698955536 6 +7.537896513938904 100 +7.173575758934021 6 +10.727712213993073 100 +6.596749633550644 16 +7.941424638032913 66 +6.480055212974548 100 +8.722104132175446 69 +7.631375938653946 66 +3.937981903553009 100 +#HACK STRING EVAL +-3.7503671646118164 100 +-6.669588088989258 100 +-7.995953559875488 100 +-4.92095947265625 100 +-6.310798645019531 100 +-4.496591567993164 100 +4.382739573717117 15 +-2.968735694885254 100 +-5.535251617431641 100 +-5.104723930358887 100 +#HACK STRING EVAL +6.153864949941635 11 +4.945752769708633 9 +8.277754008769989 9 +10.35275474190712 13 +5.650344163179398 9 +9.92192655801773 11 +9.316850364208221 10 +8.995386064052582 10 +7.509111285209656 11 +9.27760162949562 12 +#HACK STRING EVAL +9.71947193145752 11 +8.651214182376862 7 +8.137887954711914 8 +4.958065569400787 6 +7.611895263195038 8 +11.08032214641571 10 +9.929534316062927 10 +7.668625891208649 8 +5.879024982452393 6 +6.736660122871399 7 +#HACK STRING EVAL +5.834298610687256 6 +7.947747230529785 8 +4.314743757247925 4 +7.758556962013245 8 +10.77440944314003 10 +9.914957642555237 8 +7.346168339252472 8 +7.792566776275635 8 +10.009836554527283 8 +2.7323760986328125 3 +#HACK STRING EVAL +6.819895267486572 7 +5.789040684700012 6 +8.808774292469025 7 +1.190298318862915 1 +8.296438962221146 8 +5.9848551750183105 5 +4.427947074174881 5 +7.866626620292664 6 +7.8039305210113525 7 +1.738595336675644 2 +#HACK STRING EVAL +7.935068219900131 8 +3.275631308555603 3 +9.875799477100372 9 +6.046881914138794 6 +10.926620453596115 10 +8.038976967334747 8 +10.344265937805176 10 +7.229483991861343 8 +1.9989999532699585 2 +6.032447338104248 6 +#HACK STRING EVAL +4.637211799621582 100 +5.464221119880676 6 +8.486205458641052 100 +10.772761225700378 8 +12.269901633262634 100 +2.3993180990219116 2 +12.592204093933105 10 +9.09579610824585 9 +8.54663348197937 8 +5.730923116207123 6 +#HACK STRING EVAL +6.223847448825836 6 +3.8061150908470154 100 +2.7087583541870117 3 +3.723311185836792 4 +8.662603974342346 100 +7.12453019618988 100 +6.943646430969238 6 +11.348268151283264 9 +9.301883339881897 10 +9.281414210796356 10 +#HACK STRING EVAL +8.094540745019913 9 +8.121116518974304 100 +5.681110262870789 100 +1.8490899801254272 2 +7.980880081653595 100 +5.440964937210083 100 +2.477130949497223 3 +6.723384737968445 100 +5.4191731214523315 100 +4.718012094497681 100 +#HACK STRING EVAL +8.80114221572876 9 +3.3429283499717712 3 +8.189482390880585 100 +7.829261064529419 8 +10.086091995239258 8 +12.66803365945816 100 +9.819280952215195 10 +6.9309112429618835 100 +11.019678592681885 9 +5.821965277194977 6 +#HACK STRING EVAL +8.967997193336487 100 +8.935124158859253 100 +11.35765427350998 10 +7.729833483695984 8 +2.89570152759552 100 +8.258301973342896 100 +8.928422033786774 100 +5.328503906726837 6 +3.4357471466064453 4 +6.139054000377655 7 +#HACK STRING EVAL +5.216883420944214 4 +13.18329930305481 10 +9.907265067100525 8 +6.926268041133881 100 +11.233053267002106 9 +4.064905762672424 100 +0.9421440362930298 1 +5.340423166751862 100 +11.359841287136078 100 +9.464757025241852 100 +#HACK STRING EVAL +5.996541678905487 100 +10.191161930561066 100 +10.645537555217743 100 +4.037198424339294 100 +11.663651525974274 100 +2.853051006793976 3 +9.505736112594604 10 +5.896600246429443 5 +8.88951751589775 10 +8.28991311788559 100 +#HACK STRING EVAL +10.706270515918732 100 +9.34645426273346 100 +10.79639744758606 100 +5.113346040248871 100 +8.941537380218506 9 +9.178745329380035 100 +8.288512468338013 100 +10.41908723115921 9 +5.218340218067169 100 +7.31964510679245 100 +#HACK STRING EVAL +8.278983891010284 8 +2.834252893924713 100 +11.45478469133377 100 +4.226598143577576 100 +8.562659621238708 9 +8.449207067489624 100 +8.713682472705841 100 +9.28939700126648 100 +7.429606914520264 100 +12.470759123563766 11 +#HACK STRING EVAL +3.8084346055984497 100 +5.928349733352661 100 +11.242388665676117 10 +8.058322429656982 100 +5.080937147140503 100 +12.920290410518646 100 +0.3641957640647888 1 +9.402548253536224 100 +1.0212721228599548 100 +7.152795791625977 100 +#HACK STRING EVAL +6.4637457728385925 7 +3.7875452041625977 100 +10.184043049812317 100 +8.051738739013672 9 +8.762539207935333 100 +7.021410048007965 100 +7.898237407207489 100 +8.75945794582367 100 +2.4169684648513794 2 +7.9413264989852905 100 +#HACK STRING EVAL +4.788138031959534 100 +9.181240618228912 100 +9.136287808418274 100 +4.379998326301575 100 +9.152523815631866 100 +9.200820326805115 100 +9.016373634338379 9 +6.409441590309143 100 +4.732024788856506 5 +9.524616956710815 8 +#HACK STRING EVAL +4.468939304351807 6 +7.546841681003571 100 +7.072476506233215 100 +10.566696047782898 100 +6.373043179512024 100 +7.984097599983215 7 +6.739117830991745 7 +8.46365112066269 100 +7.415590584278107 100 +3.8851922154426575 100 +#HACK STRING EVAL +-3.7503671646118164 100 +-6.669588088989258 100 +-7.995953559875488 100 +-4.92095947265625 100 +0.4160881042480469 100 +-4.496591567993164 100 +-1.8359127044677734 100 +-2.968735694885254 100 +-5.535251617431641 100 +-5.104723930358887 100 +#HACK STRING EVAL +6.279469430446625 9 +5.208711266517639 8 +6.84302544593811 100 +9.154145240783691 100 +4.474870920181274 100 +9.821542918682098 14 +7.957018136978149 100 +7.462389707565308 100 +6.32072114944458 100 +8.104987859725952 100 +#HACK STRING EVAL +9.423466205596924 11 +8.351568907499313 8 +8.216377079486847 9 +4.6488858461380005 6 +7.4556224048137665 9 +10.809939980506897 11 +9.842160642147064 11 +7.310408234596252 8 +6.0247838497161865 7 +6.80091655254364 7 +#HACK STRING EVAL +6.1182252168655396 7 +7.853924930095673 8 +4.20554780960083 4 +7.618032991886139 8 +10.96361768245697 10 +9.790180802345276 8 +7.438938856124878 8 +7.705836296081543 8 +9.968870162963867 8 +2.812936305999756 3 +#HACK STRING EVAL +6.780524492263794 7 +5.915796339511871 6 +8.5910325050354 7 +1.1846603155136108 1 +8.48517793416977 8 +6.2945380210876465 5 +4.533729285001755 5 +7.873458623886108 6 +8.040667533874512 7 +1.9246229529380798 2 +#HACK STRING EVAL +7.903108298778534 8 +3.417933464050293 3 +9.860237836837769 9 +6.378161191940308 6 +11.060532957315445 10 +8.075929284095764 8 +10.665367662906647 10 +7.263342201709747 8 +1.969520628452301 2 +6.109506845474243 6 +#HACK STRING EVAL +4.959715127944946 5 +5.505188316106796 6 +8.600837707519531 7 +10.665625929832458 8 +12.54722273349762 10 +2.4462450742721558 2 +12.513755559921265 10 +9.473274767398834 9 +8.682815074920654 8 +5.7761141657829285 6 +#HACK STRING EVAL +6.313274621963501 6 +4.149107038974762 4 +2.8736608028411865 3 +3.692173480987549 4 +8.981123954057693 10 +7.197376072406769 100 +7.0361515283584595 6 +11.14345932006836 9 +9.317192316055298 10 +9.305774807929993 10 +#HACK STRING EVAL +7.899849355220795 100 +8.444545775651932 8 +5.9510789811611176 7 +1.8712916374206543 2 +7.854494273662567 100 +5.43723601102829 100 +2.4329820573329926 3 +6.958400219678879 7 +5.786084771156311 6 +4.745466589927673 100 +#HACK STRING EVAL +8.739343255758286 10 +3.2279903888702393 100 +8.50719639658928 8 +7.529992520809174 100 +9.952744960784912 8 +12.81603741645813 100 +9.884664446115494 11 +6.855063796043396 100 +11.154115080833435 9 +5.60866117477417 6 +#HACK STRING EVAL +8.84818571805954 100 +9.009705662727356 100 +11.354346334934235 10 +7.681864142417908 8 +2.9702831506729126 100 +8.435151934623718 8 +8.808596432209015 100 +5.263169944286346 5 +3.1403245329856873 100 +5.909680187702179 100 +#HACK STRING EVAL +5.207172870635986 4 +13.154069066047668 10 +9.69873434305191 100 +6.7408958077430725 100 +11.235575318336487 9 +4.0037713050842285 100 +0.9462223052978516 1 +5.6800254583358765 6 +11.713104814291 11 +9.663968741893768 100 +#HACK STRING EVAL +5.917748928070068 100 +10.170765459537506 100 +10.865458369255066 10 +4.190006375312805 5 +11.9911929666996 10 +2.698923408985138 100 +9.247322618961334 100 +5.889277338981628 5 +8.686996459960938 100 +8.569363832473755 9 +#HACK STRING EVAL +10.829796075820923 9 +9.489267468452454 100 +10.679134488105774 100 +5.407732009887695 6 +8.69893878698349 100 +9.281325995922089 10 +8.413928151130676 100 +10.450757265090942 9 +5.10194456577301 100 +7.462462663650513 100 +#HACK STRING EVAL +8.206133008003235 8 +2.6670429706573486 100 +11.628361105918884 100 +4.136563420295715 100 +8.23183524608612 9 +8.359174072742462 100 +8.546401023864746 100 +9.438416481018066 100 +7.262302577495575 100 +12.197540819644928 100 +#HACK STRING EVAL +3.9429489970207214 100 +6.263928234577179 6 +11.379340469837189 10 +8.047515988349915 100 +4.934296727180481 100 +13.29022991657257 10 +0.3825625479221344 1 +9.424796104431152 100 +1.0434902906417847 100 +7.445310175418854 8 +#HACK STRING EVAL +6.5974578857421875 7 +3.8142848014831543 100 +10.160232126712799 100 +7.7951560616493225 100 +8.864068269729614 100 +6.997634708881378 100 +8.067974001169205 9 +8.860558331012726 100 +2.466044068336487 2 +8.04332983493805 100 +#HACK STRING EVAL +4.819764018058777 100 +9.082825124263763 100 +9.309907495975494 100 +4.556538939476013 100 +9.299180686473846 18 +9.378854095935822 100 +8.953286409378052 100 +6.825946509838104 6 +4.71485161781311 6 +9.21001273393631 100 +#HACK STRING EVAL +4.522183775901794 5 +7.664863407611847 100 +7.0281729102134705 100 +10.662391781806946 100 +6.467475354671478 100 +7.974195241928101 7 +6.424801707267761 100 +8.489864587783813 100 +7.510352671146393 100 +3.7716774344444275 100 +#HACK STRING EVAL +-0.29006385803222656 100 +-3.209284782409668 100 +-4.535650253295898 100 +-1.4606571197509766 100 +-2.850496292114258 100 +-1.0362892150878906 100 +-5.835520267486572 100 +0.49156665802001953 100 +-2.074948310852051 100 +-1.6444215774536133 100 +#HACK STRING EVAL +6.153945356607437 9 +4.9433059096336365 6 +8.054848819971085 22 +10.384417653083801 16 +5.709148854017258 12 +9.894213557243347 12 +9.103969871997833 23 +8.673213213682175 23 +7.577702969312668 14 +9.256295949220657 15 +#HACK STRING EVAL +9.854133933782578 11 +8.427368402481079 7 +7.875953793525696 9 +5.083258032798767 6 +7.657807886600494 8 +10.715822339057922 9 +9.653861165046692 10 +7.375465154647827 8 +6.047962665557861 7 +6.52009642124176 7 +#HACK STRING EVAL +6.160887449979782 7 +7.774721443653107 8 +4.33281147480011 4 +7.827552676200867 8 +10.862525671720505 10 +9.892272174358368 8 +7.397484838962555 8 +7.641548752784729 8 +9.989415526390076 8 +2.6419249176979065 3 +#HACK STRING EVAL +6.737555623054504 7 +5.8876552283763885 6 +8.716613411903381 7 +1.1958811283111572 1 +8.54835832118988 8 +6.111787438392639 5 +4.478089809417725 5 +7.887208461761475 6 +7.993856430053711 7 +1.9235344529151917 2 +#HACK STRING EVAL +7.838002383708954 8 +3.3156228065490723 3 +9.723491460084915 9 +6.292858958244324 6 +10.937106132507324 9 +8.052244246006012 8 +10.678099691867828 10 +7.178789377212524 8 +1.98728346824646 2 +5.930929183959961 6 +#HACK STRING EVAL +4.908179461956024 5 +5.6419837474823 6 +8.571600615978241 7 +10.67663499712944 9 +12.394994348287582 10 +2.40663480758667 2 +12.471927404403687 10 +9.405215620994568 9 +8.444398164749146 8 +5.799235582351685 6 +#HACK STRING EVAL +6.259880065917969 6 +3.7712952494621277 100 +2.888824701309204 3 +3.5240712761878967 100 +8.833026707172394 10 +7.048048734664917 100 +6.959584355354309 6 +11.295777678489685 9 +9.103113174438477 10 +9.396331369876862 10 +#HACK STRING EVAL +8.145994544029236 9 +8.558571755886078 8 +5.652395725250244 100 +1.8293574750423431 2 +8.038797914981842 100 +5.351219058036804 100 +2.4387102127075195 3 +6.781302094459534 100 +5.573114037513733 6 +4.820780694484711 100 +#HACK STRING EVAL +8.867784172296524 10 +3.06900292634964 100 +8.416794389486313 8 +7.823940008878708 9 +10.140365779399872 8 +12.657049477100372 100 +9.78075984120369 18 +7.0275559425354 17 +11.114203214645386 9 +5.739595890045166 6 +#HACK STRING EVAL +9.00145673751831 100 +9.125753223896027 100 +11.50535798072815 10 +7.70134961605072 8 +3.1200444102287292 4 +8.291768610477448 100 +9.15495765209198 8 +5.2590493857860565 5 +3.293612480163574 100 +6.311359763145447 7 +#HACK STRING EVAL +5.238387107849121 4 +13.138463973999023 10 +9.850921213626862 100 +6.881994307041168 100 +11.24952757358551 9 +3.8579457998275757 100 +0.9588590860366821 1 +5.671657979488373 6 +11.97709983587265 10 +9.847899496555328 9 +#HACK STRING EVAL +6.034544110298157 100 +10.203887939453125 100 +10.895116776227951 11 +4.060418665409088 100 +11.649588167667389 100 +2.8539504408836365 3 +9.520333647727966 10 +5.855411946773529 5 +8.778497695922852 100 +8.437058866024017 100 +#HACK STRING EVAL +10.54959124326706 100 +9.562351822853088 100 +10.876161456108093 9 +5.4915048480033875 6 +8.862244367599487 9 +9.432759821414948 10 +8.290428698062897 100 +10.679631650447845 9 +5.219855427742004 100 +7.556907296180725 100 +#HACK STRING EVAL +8.244074404239655 8 +2.9291086196899414 3 +11.658528447151184 100 +4.188403427600861 100 +8.188709497451782 9 +8.273911774158478 100 +8.822214841842651 9 +9.469148695468903 100 +7.517143696546555 8 +12.227693557739258 100 +#HACK STRING EVAL +4.126795649528503 5 +6.147564113140106 100 +11.31804096698761 10 +8.028591692447662 100 +4.877688407897949 100 +13.30095911026001 10 +0.3817707598209381 1 +9.652000069618225 10 +1.0766184329986572 100 +7.268299460411072 100 +#HACK STRING EVAL +6.1239699721336365 100 +3.8286982774734497 100 +10.165176331996918 100 +7.809609591960907 100 +8.815561890602112 100 +7.002511441707611 100 +8.053363233804703 9 +8.973394364118576 9 +2.445148229598999 2 +8.136548459529877 100 +#HACK STRING EVAL +4.727257192134857 100 +9.384450495243073 10 +9.471574902534485 7 +4.52790504693985 100 +9.091549158096313 100 +9.58648157119751 9 +9.144766569137573 9 +6.7069293558597565 6 +4.833862841129303 6 +9.49623817205429 8 +#HACK STRING EVAL +4.721530854701996 5 +7.756379783153534 100 +7.207006335258484 6 +10.783645510673523 10 +6.468363404273987 100 +7.954935550689697 7 +6.569757580757141 6 +8.67330813407898 100 +7.511645257472992 100 +3.809648871421814 100 +#HACK STRING EVAL +0.24425697326660156 100 +-6.669588088989258 100 +-4.00132942199707 100 +8.723642855882645 32 +-6.310798645019531 100 +9.206400990486145 19 +-5.301114559173584 100 +-2.968735694885254 100 +-1.5406274795532227 100 +-5.104723930358887 100 +#HACK STRING EVAL +6.243300139904022 9 +5.218166947364807 8 +7.996024817228317 19 +10.301670372486115 16 +5.713277190923691 8 +9.858533293008804 17 +9.097836554050446 20 +8.632827281951904 20 +7.468609005212784 18 +9.382098317146301 11 +#HACK STRING EVAL +9.822313249111176 11 +8.675039529800415 7 +7.917456030845642 8 +5.117711246013641 6 +7.732499420642853 8 +10.989262640476227 10 +9.911355376243591 10 +7.625390648841858 8 +5.819939136505127 6 +6.838441550731659 7 +#HACK STRING EVAL +5.820311069488525 6 +7.898846864700317 8 +4.243642449378967 4 +7.707642436027527 8 +10.802921265363693 10 +9.660410523414612 8 +7.3847376704216 8 +7.790679693222046 8 +10.020368576049805 8 +2.7350319027900696 3 +#HACK STRING EVAL +6.7996116280555725 7 +5.917615920305252 6 +8.627890050411224 7 +1.1613507270812988 1 +8.277477264404297 7 +6.028522849082947 5 +4.310431480407715 4 +7.937914133071899 6 +8.122877061367035 7 +1.8140833377838135 2 +#HACK STRING EVAL +7.867380261421204 8 +3.4286499619483948 3 +9.760114014148712 9 +6.297006547451019 6 +10.901076525449753 10 +8.014710783958435 8 +10.580411672592163 10 +7.280703842639923 8 +2.1505938172340393 2 +6.049351871013641 6 +#HACK STRING EVAL +4.842934846878052 5 +5.357100337743759 6 +8.738991022109985 7 +10.701062083244324 8 +12.313896894454956 100 +2.37805712223053 2 +12.726392149925232 10 +9.46134626865387 9 +8.385815382003784 8 +5.523526549339294 6 +#HACK STRING EVAL +6.354707837104797 6 +4.079822421073914 4 +2.73889297246933 3 +3.675166130065918 4 +8.936510354280472 10 +7.279150456190109 8 +6.533032417297363 100 +11.33301329612732 9 +8.770122468471527 100 +9.352826118469238 10 +#HACK STRING EVAL +7.869707524776459 100 +8.360556900501251 8 +5.77699339389801 100 +1.8666044473648071 2 +7.914733350276947 100 +5.407093942165375 100 +2.4911733269691467 3 +6.702782988548279 100 +5.781500458717346 6 +4.720927834510803 100 +#HACK STRING EVAL +8.646577894687653 100 +3.112985670566559 100 +8.1645148396492 100 +7.8151728212833405 9 +10.028007924556732 8 +12.701031982898712 100 +9.783048689365387 10 +6.788811087608337 100 +11.194642782211304 9 +5.44853675365448 100 +#HACK STRING EVAL +8.88541567325592 100 +9.114842176437378 100 +11.400342166423798 10 +7.673210263252258 8 +3.075420081615448 100 +8.175727427005768 100 +8.845827102661133 100 +5.254616022109985 5 +3.4003729224205017 5 +6.195006012916565 7 +#HACK STRING EVAL +5.272568225860596 4 +13.096140742301941 10 +9.86588603258133 18 +6.820926308631897 100 +11.322917222976685 9 +4.153600513935089 13 +0.9330641031265259 1 +5.4661073088645935 100 +11.485426723957062 100 +9.80406939983368 9 +#HACK STRING EVAL +6.055018961429596 100 +10.300982236862183 8 +10.813132762908936 100 +4.220988094806671 5 +11.59806114435196 100 +2.533959150314331 100 +9.09949779510498 100 +5.84150493144989 5 +8.824277460575104 100 +8.457385838031769 100 +#HACK STRING EVAL +10.533409178256989 100 +9.640004098415375 22 +10.623492538928986 100 +5.283744156360626 100 +8.744990825653076 100 +9.005813300609589 100 +8.458976149559021 100 +10.418975591659546 9 +5.045226097106934 100 +7.677685022354126 8 +#HACK STRING EVAL +8.244978904724121 8 +2.8270614743232727 100 +11.457642138004303 100 +4.337018996477127 19 +8.233388304710388 9 +8.453078985214233 100 +8.706302046775818 100 +9.268046975135803 100 +7.422130048274994 100 +12.320465952157974 11 +#HACK STRING EVAL +3.7743683457374573 100 +6.208017796278 6 +11.22487998008728 73 +8.186741530895233 59 +5.106708586215973 100 +13.268326163291931 10 +0.3200502395629883 100 +9.628447771072388 10 +1.2236453294754028 36 +7.490011811256409 8 +#HACK STRING EVAL +6.546425938606262 7 +3.9937044382095337 44 +10.316336214542389 43 +7.970456957817078 52 +8.668218731880188 100 +6.844804048538208 100 +8.107867062091827 9 +9.024279177188873 9 +2.4433261156082153 2 +7.846805930137634 100 +#HACK STRING EVAL +4.9411269426345825 18 +9.288332760334015 100 +9.084145426750183 100 +4.3298720717430115 100 +9.61493992805481 10 +9.531646490097046 9 +9.001444190740585 17 +6.359889984130859 100 +4.787615060806274 5 +9.417626798152924 100 +#HACK STRING EVAL +4.416544109582901 44 +7.465511381626129 100 +7.205659866333008 6 +10.782000601291656 35 +6.597033202648163 25 +7.944126516580582 25 +6.554182976484299 33 +8.72453224658966 28 +7.6308533847332 27 +4.009629130363464 38 +#HACK STRING EVAL +-3.7503671646118164 100 +-6.669588088989258 100 +5.180831789970398 17 +8.318854629993439 25 +-6.310798645019531 100 +8.693064033985138 27 +3.9108246564865112 16 +-2.968735694885254 100 +7.643557846546173 8 +-5.104723930358887 100 +#HACK STRING EVAL +-3.5310564041137695 100 +-4.670470714569092 100 +-1.6055059432983398 100 +9.990200638771057 10 +5.654489040374756 5 +0.22601032257080078 100 +-0.4914989471435547 100 +-0.9861316680908203 100 +7.034305453300476 9 +8.74982213973999 8 +#HACK STRING EVAL +-0.13811779022216797 100 +8.555721640586853 7 +-1.7374906539916992 100 +-4.911149978637695 100 +-2.309335231781006 100 +1.1279926300048828 100 +9.270938277244568 11 +7.0379427671432495 9 +5.425108075141907 7 +-3.102971076965332 100 +#HACK STRING EVAL +5.670800805091858 6 +7.736049652099609 8 +3.673248052597046 4 +3.8792781829833984 100 +10.14450991153717 9 +9.086544632911682 8 +3.4805922508239746 100 +7.613076329231262 8 +6.132021903991699 100 +2.5952104330062866 3 +#HACK STRING EVAL +6.695021986961365 7 +5.200091361999512 10 +8.126245200634003 7 +0.8714110851287842 1 +8.178871273994446 7 +6.177776217460632 5 +3.816335380077362 5 +7.499484360218048 6 +7.321289658546448 6 +1.1564284563064575 1 +#HACK STRING EVAL +7.303165674209595 13 +3.254235327243805 3 +9.62517511844635 16 +6.04854428768158 6 +11.199024379253387 10 +7.970274925231934 8 +9.839454591274261 9 +7.227851748466492 12 +1.8777304887771606 2 +5.858513712882996 5 +#HACK STRING EVAL +4.857699811458588 5 +5.063076019287109 5 +8.625640988349915 11 +10.822550117969513 14 +12.325289368629456 9 +2.3388575315475464 2 +12.741023659706116 15 +8.725348174571991 8 +7.883552074432373 7 +5.350101709365845 7 +#HACK STRING EVAL +6.465976655483246 9 +4.1369746923446655 4 +2.8999158143997192 3 +3.9219512939453125 4 +8.86326003074646 9 +7.1100587248802185 7 +6.670606076717377 9 +10.710482001304626 8 +8.970320224761963 9 +8.837131679058075 9 +#HACK STRING EVAL +8.080179512500763 8 +8.105030179023743 9 +5.973527908325195 6 +1.3323025703430176 1 +8.284787774085999 8 +5.493114948272705 4 +1.9981055855751038 2 +6.925599575042725 6 +5.912810802459717 6 +4.8532410860061646 4 +#HACK STRING EVAL +8.294064044952393 8 +3.126140594482422 3 +8.16828989982605 6 +7.660725116729736 7 +9.332978248596191 7 +12.394394874572754 9 +9.693102955818176 9 +7.170834720134735 7 +11.138776659965515 9 +5.946889877319336 6 +#HACK STRING EVAL +8.792295634746552 8 +8.992170453071594 8 +10.961163401603699 9 +7.867859959602356 8 +3.1500748991966248 3 +8.21934700012207 6 +9.218563914299011 8 +4.758637726306915 4 +3.6411635279655457 4 +5.845736265182495 6 +#HACK STRING EVAL +5.0723350048065186 4 +12.659545302391052 9 +9.562892436981201 7 +7.056931018829346 6 +10.906207382678986 9 +3.942310631275177 4 +0.9457265138626099 1 +5.755048990249634 6 +11.385231018066406 9 +9.852900803089142 9 +#HACK STRING EVAL +5.73747193813324 6 +9.949385643005371 8 +11.02604365348816 10 +3.97149920463562 4 +11.568231463432312 9 +2.9009021520614624 3 +9.569988429546356 10 +5.217777848243713 4 +8.862122654914856 9 +8.463022291660309 9 +#HACK STRING EVAL +10.476787269115448 8 +9.963252782821655 8 +11.26234495639801 9 +5.416366696357727 6 +9.193496584892273 9 +9.002249479293823 9 +8.835649967193604 8 +10.644249320030212 9 +4.8022401332855225 5 +8.018100500106812 8 +#HACK STRING EVAL +8.271698713302612 8 +3.0043419003486633 3 +11.676635026931763 9 +4.3902915716171265 4 +7.890985667705536 8 +8.275585651397705 9 +9.132441759109497 9 +9.671203136444092 8 +7.481678545475006 7 +12.181931495666504 9 +#HACK STRING EVAL +3.6766058802604675 4 +6.012807905673981 5 +11.3445543050766 9 +7.802715599536896 7 +5.137809634208679 5 +12.706938982009888 9 +0.29299211502075195 1 +9.247895896434784 9 +1.0035920143127441 1 +7.004661321640015 7 +#HACK STRING EVAL +6.064632773399353 6 +3.7725746631622314 4 +9.83968210220337 8 +8.007780611515045 8 +8.970101237297058 8 +7.069725453853607 7 +7.9429891705513 8 +8.563364088535309 8 +2.4179205894470215 2 +8.397390127182007 6 +#HACK STRING EVAL +5.047569394111633 5 +9.399255931377411 10 +9.699734926223755 7 +4.591809689998627 5 +9.569580495357513 10 +9.542823255062103 9 +8.540849566459656 8 +6.705582618713379 5 +4.381331920623779 4 +9.721714615821838 8 +#HACK STRING EVAL +4.564748764038086 5 +8.213271379470825 8 +6.95683479309082 5 +10.938478112220764 9 +6.277543425559998 5 +7.9776611328125 7 +6.0566717982292175 5 +8.833106994628906 9 +7.328388810157776 7 +3.723255455493927 4 +#HACK STRING EVAL +-1.4054603576660156 100 +-4.448149681091309 100 +-5.77601432800293 100 +-2.7010202407836914 100 +-4.090859413146973 100 +-2.2766523361206055 100 +-7.0758843421936035 100 +-0.7487964630126953 100 +-3.1687822341918945 100 +-2.884784698486328 100 +#HACK STRING EVAL +5.677076578140259 12 +4.46114194393158 10 +7.573733448982239 13 +9.869380176067352 12 +5.221141338348389 7 +9.398294985294342 16 +8.69952768087387 14 +8.109531462192535 13 +7.090352356433868 12 +8.88538008928299 11 +#HACK STRING EVAL +9.218906998634338 10 +8.558544278144836 7 +7.465876936912537 8 +4.407675623893738 5 +6.926080942153931 7 +10.805794358253479 9 +9.319569706916809 10 +7.1187708377838135 8 +5.409777224063873 6 +5.966532826423645 6 +#HACK STRING EVAL +5.749221444129944 6 +7.7960216999053955 8 +4.127429246902466 4 +7.709489345550537 8 +10.379866003990173 9 +8.977509498596191 7 +6.825451731681824 7 +7.644044637680054 8 +9.758957147598267 8 +1.9316338300704956 2 +#HACK STRING EVAL +6.745368838310242 7 +5.519041299819946 5 +8.562182307243347 7 +1.123488426208496 1 +8.210710525512695 7 +6.188555657863617 5 +4.183086276054382 4 +7.930420517921448 6 +7.353883445262909 6 +1.3043906688690186 1 +#HACK STRING EVAL +7.602144360542297 7 +3.3358479142189026 3 +9.315849840641022 8 +6.339080214500427 6 +10.920983016490936 9 +7.987700581550598 8 +10.70091724395752 10 +6.750524938106537 7 +2.1004645824432373 2 +5.772363364696503 5 +#HACK STRING EVAL +4.93053412437439 5 +5.011416494846344 5 +8.801079034805298 7 +10.696310639381409 8 +12.068384170532227 9 +2.448928952217102 2 +12.097500801086426 9 +8.559853315353394 8 +8.65619146823883 8 +5.753073871135712 6 +#HACK STRING EVAL +6.317312479019165 6 +4.091058194637299 4 +2.8382482528686523 3 +3.7191861271858215 4 +8.627062261104584 9 +7.026709675788879 7 +6.311347961425781 5 +11.39376026391983 9 +8.648327112197876 9 +8.702446043491364 9 +#HACK STRING EVAL +7.853300988674164 8 +8.063067734241486 7 +5.86069929599762 6 +1.306060791015625 1 +8.043071866035461 8 +5.354470491409302 4 +1.9554746747016907 2 +6.769051790237427 6 +5.757829427719116 6 +4.774630308151245 4 +#HACK STRING EVAL +9.034712612628937 9 +3.4491295218467712 3 +7.959701418876648 6 +7.46575665473938 7 +9.931891083717346 8 +12.825292766094208 10 +9.421553373336792 9 +7.003383755683899 7 +11.019893169403076 9 +5.673236846923828 6 +#HACK STRING EVAL +8.919042885303497 8 +9.02531772851944 8 +11.431546032428741 10 +7.626355707645416 8 +3.001864194869995 3 +7.917459845542908 6 +9.183589816093445 8 +4.779336929321289 4 +3.5010746717453003 4 +5.835262954235077 6 +#HACK STRING EVAL +5.167585968971252 4 +13.188474416732788 10 +9.86951732635498 8 +6.8153210282325745 6 +11.208670020103455 9 +3.9463822841644287 4 +0.9513099193572998 1 +5.7041414976119995 6 +12.015401601791382 10 +9.88407850265503 9 +#HACK STRING EVAL +6.291538119316101 6 +10.121272385120392 8 +10.981117904186249 10 +3.8440850973129272 4 +11.517300486564636 9 +2.8795303106307983 3 +9.590958595275879 10 +5.104642391204834 4 +8.719789922237396 9 +8.669788718223572 9 +#HACK STRING EVAL +10.327147126197815 8 +9.501702189445496 8 +10.882286429405212 9 +5.531369924545288 6 +8.911094784736633 9 +9.592777967453003 10 +8.512150883674622 8 +10.692993760108948 9 +5.142122566699982 5 +7.63880467414856 8 +#HACK STRING EVAL +7.742602825164795 7 +2.907249867916107 3 +11.55355966091156 9 +4.2135027050971985 4 +8.291919529438019 9 +8.715961933135986 9 +9.049503564834595 9 +9.347619950771332 8 +7.389916360378265 7 +11.866234302520752 9 +#HACK STRING EVAL +3.731126844882965 4 +6.020756840705872 5 +10.93038123846054 9 +8.066699504852295 7 +4.897031366825104 5 +13.374675393104553 10 +0.4301268756389618 1 +9.215664863586426 9 +0.9939450025558472 1 +7.385909199714661 8 +#HACK STRING EVAL +5.971229732036591 6 +3.7670175433158875 4 +10.360648155212402 9 +7.8028950691223145 8 +8.809513092041016 8 +6.938753247261047 7 +7.791137218475342 8 +8.788468539714813 8 +2.4196741580963135 2 +8.008363127708435 6 +#HACK STRING EVAL +4.7637529373168945 5 +9.445238173007965 10 +9.377156615257263 7 +4.6334006786346436 5 +9.705934166908264 10 +9.527951002120972 9 +8.974092543125153 9 +6.569938063621521 5 +4.210530459880829 4 +9.560588002204895 8 +#HACK STRING EVAL +4.470890164375305 5 +7.738147556781769 8 +7.252026915550232 6 +10.871177315711975 9 +6.178730249404907 5 +8.014536201953888 7 +6.102986991405487 5 +8.71311628818512 9 +7.615756869316101 7 +3.748241901397705 4 +#HACK STRING EVAL +-3.7503671646118164 100 +-6.669588088989258 100 +-7.995953559875488 100 +8.24241715669632 27 +6.8755035400390625 31 +8.671626269817352 29 +3.9041269421577454 12 +10.174369871616364 30 +-5.535251617431641 100 +8.052942276000977 26 +#HACK STRING EVAL +5.619724631309509 12 +4.552429020404816 11 +7.528866648674011 12 +10.066438257694244 9 +5.451976418495178 5 +9.433687567710876 14 +8.813687264919281 14 +8.2022003531456 13 +7.376253128051758 8 +8.843863487243652 10 +#HACK STRING EVAL +9.422114133834839 10 +8.634504735469818 7 +8.018572330474854 8 +4.54811429977417 5 +6.956747472286224 7 +10.188180387020111 9 +9.114144623279572 9 +7.58523029088974 8 +5.7617655992507935 6 +6.371476590633392 6 +#HACK STRING EVAL +5.814825773239136 6 +7.064453899860382 7 +4.2387049198150635 4 +7.714540123939514 8 +10.39992892742157 9 +9.773693323135376 8 +6.812363684177399 7 +7.76985365152359 8 +9.372642755508423 7 +1.9056394696235657 2 +#HACK STRING EVAL +6.731841683387756 7 +5.4887890219688416 5 +8.631198108196259 7 +1.1819764375686646 1 +8.164858162403107 7 +6.056710481643677 5 +4.275099217891693 4 +7.853689670562744 6 +7.231969237327576 6 +1.326801061630249 1 +#HACK STRING EVAL +7.544692814350128 7 +3.3525127172470093 3 +9.26132047176361 8 +6.218110918998718 6 +10.803838789463043 9 +8.001941680908203 8 +10.539739191532135 10 +6.715208947658539 7 +2.073453187942505 2 +5.7388306856155396 5 +#HACK STRING EVAL +4.811056971549988 5 +4.9920390248298645 5 +8.72795170545578 7 +10.669973850250244 8 +12.113903760910034 9 +2.4250789880752563 2 +12.77142584323883 10 +8.576184511184692 8 +8.576193392276764 8 +5.7781177163124084 6 +#HACK STRING EVAL +6.236102104187012 6 +3.9519505500793457 4 +2.7236738801002502 3 +3.808649957180023 4 +8.7170769572258 9 +6.986597955226898 7 +6.365009307861328 5 +11.200201988220215 9 +8.644501090049744 9 +8.63322901725769 9 +#HACK STRING EVAL +7.926543474197388 8 +8.06740802526474 7 +5.751794755458832 6 +1.3179676532745361 1 +8.087746262550354 8 +5.276997804641724 4 +2.46015465259552 3 +6.711429297924042 6 +5.49571567773819 6 +4.767374753952026 4 +#HACK STRING EVAL +9.121251702308655 9 +3.309056282043457 3 +8.400131523609161 7 +7.3157947063446045 7 +9.971865892410278 8 +12.73104727268219 10 +9.3420330286026 9 +6.874563097953796 7 +11.021454751491547 9 +5.5755836963653564 6 +#HACK STRING EVAL +8.9187371134758 8 +8.925725877285004 8 +11.433376431465149 10 +7.677306532859802 8 +2.985858678817749 3 +8.563404440879822 7 +9.02274477481842 8 +5.32707941532135 5 +2.88593453168869 3 +5.825172185897827 6 +#HACK STRING EVAL +5.189161777496338 4 +13.228269219398499 10 +9.833918035030365 8 +6.7454036474227905 6 +11.224571764469147 9 +3.8720837831497192 4 +0.9588360786437988 1 +5.690085053443909 6 +11.78907036781311 10 +9.718745708465576 9 +#HACK STRING EVAL +6.090857028961182 6 +10.201201319694519 8 +10.898309350013733 10 +3.797667622566223 4 +11.60955011844635 9 +2.90105938911438 3 +9.490566372871399 10 +5.108049631118774 4 +8.623591184616089 9 +8.363829731941223 9 +#HACK STRING EVAL +10.836789608001709 9 +9.443619906902313 8 +10.789477288722992 9 +5.520484924316406 6 +8.807584643363953 9 +9.608415842056274 10 +8.393968045711517 8 +10.601214289665222 9 +5.046808242797852 5 +7.533772528171539 8 +#HACK STRING EVAL +8.237029671669006 8 +2.866899788379669 3 +11.553701043128967 9 +4.120765745639801 4 +7.68544065952301 8 +8.426182210445404 9 +8.75005054473877 9 +9.252606213092804 8 +7.260896563529968 7 +11.79919707775116 9 +#HACK STRING EVAL +3.8851580023765564 4 +5.862396240234375 5 +11.373758435249329 10 +7.921870410442352 7 +4.826148509979248 5 +13.298025131225586 10 +0.3709006607532501 1 +9.321471691131592 9 +1.0234251022338867 1 +7.477885961532593 8 +#HACK STRING EVAL +6.381060898303986 7 +3.784924864768982 4 +10.168004870414734 9 +7.80863630771637 8 +8.64653080701828 8 +6.857953429222107 7 +7.771783232688904 8 +8.66422164440155 8 +2.449071168899536 2 +7.9194947481155396 6 +#HACK STRING EVAL +4.869090795516968 5 +9.345124125480652 10 +9.213906049728394 7 +4.575713515281677 5 +9.310802042484283 10 +9.496176421642303 9 +8.865683376789093 9 +6.478553414344788 5 +4.75563657283783 5 +9.41614454984665 8 +#HACK STRING EVAL +4.4126264452934265 5 +7.674594163894653 8 +7.162147700786591 6 +10.703261375427246 9 +6.150736093521118 5 +7.872803270816803 7 +6.084340155124664 5 +8.442215144634247 9 +7.532873094081879 7 +3.6888131499290466 4 +#HACK STRING EVAL +-3.7503671646118164 100 +-6.669588088989258 100 +-7.995953559875488 100 +-4.92095947265625 100 +-6.310798645019531 100 +-4.496591567993164 100 +3.861271023750305 21 +-2.968735694885254 100 +-5.535251617431641 100 +-5.104723930358887 100 +#HACK STRING EVAL +5.883889019489288 7 +4.521680235862732 5 +7.513023734092712 10 +9.938129186630249 10 +5.215961456298828 6 +9.589709103107452 11 +8.696838319301605 11 +8.387576043605804 11 +7.201474666595459 9 +8.931851208209991 9 +#HACK STRING EVAL +9.374665021896362 10 +7.875059366226196 6 +7.8917542695999146 8 +4.5137510895729065 5 +7.060928463935852 7 +10.91916048526764 9 +9.082121729850769 9 +7.519306540489197 8 +5.7263107895851135 6 +6.161062180995941 6 +#HACK STRING EVAL +5.655864953994751 6 +7.75082790851593 8 +4.135713577270508 4 +7.629908323287964 8 +10.401870846748352 9 +9.15232789516449 7 +6.7185362577438354 7 +7.6062610149383545 8 +9.266782999038696 7 +2.6458446979522705 3 +#HACK STRING EVAL +6.646586716175079 7 +5.440497577190399 5 +8.6033456325531 7 +1.101889967918396 1 +8.11598914861679 7 +6.284524083137512 5 +4.225857436656952 4 +7.881002068519592 6 +7.364149212837219 6 +1.2524436712265015 1 +#HACK STRING EVAL +7.540386617183685 7 +3.321972131729126 3 +9.252022564411163 8 +6.2171207666397095 6 +10.940676212310791 9 +7.915536880493164 8 +10.607275664806366 10 +6.718454420566559 7 +2.085836172103882 2 +5.700707674026489 5 +#HACK STRING EVAL +4.88448166847229 5 +4.984133303165436 5 +8.677709817886353 7 +10.611352443695068 8 +12.157405853271484 9 +2.441638231277466 2 +12.653615474700928 10 +8.591157078742981 8 +8.42875051498413 8 +5.760806858539581 6 +#HACK STRING EVAL +6.264048397541046 6 +4.064350247383118 4 +2.8404301404953003 3 +3.6166118383407593 4 +8.612112522125244 9 +6.870912969112396 7 +6.366198182106018 5 +11.29962307214737 9 +8.691060185432434 9 +9.16858196258545 10 +#HACK STRING EVAL +7.776387929916382 8 +8.012472569942474 7 +5.812124192714691 6 +1.3301749229431152 1 +7.905767917633057 8 +5.310029745101929 4 +2.5325253009796143 3 +6.678494095802307 6 +5.746864438056946 6 +4.814166069030762 4 +#HACK STRING EVAL +8.753130495548248 9 +3.3105548620224 3 +8.537829756736755 7 +7.352075576782227 7 +10.071678221225739 8 +12.89633983373642 10 +9.392543971538544 9 +6.9353256821632385 7 +11.06075644493103 9 +5.72729617357254 6 +#HACK STRING EVAL +8.936338424682617 8 +8.910850465297699 8 +11.401347041130066 10 +7.630872964859009 8 +2.8620924949645996 3 +8.354676127433777 7 +9.076991021633148 8 +4.755031704902649 4 +3.4907320737838745 4 +5.764264464378357 6 +#HACK STRING EVAL +5.161735653877258 4 +13.16019356250763 10 +9.874776244163513 8 +6.747594654560089 6 +11.321098625659943 9 +3.9550758004188538 4 +0.9479318857192993 1 +5.902975797653198 6 +11.952566802501678 10 +9.81643933057785 9 +#HACK STRING EVAL +6.080150723457336 6 +10.022854804992676 8 +10.867082238197327 10 +3.7457967400550842 4 +12.132060766220093 10 +2.821012258529663 3 +9.774587571620941 10 +5.063295602798462 4 +8.743524551391602 9 +8.566873490810394 9 +#HACK STRING EVAL +10.847960352897644 9 +9.575592339038849 8 +10.720859050750732 9 +5.419663488864899 6 +8.914573192596436 9 +9.319994807243347 10 +8.430023849010468 8 +10.497173547744751 9 +5.073047876358032 5 +7.5426570773124695 8 +#HACK STRING EVAL +8.150438904762268 8 +2.8299957513809204 3 +11.610964179039001 9 +4.151318609714508 4 +7.736770689487457 8 +8.497636198997498 9 +8.89724338054657 9 +9.218148946762085 8 +7.269273102283478 7 +11.820441246032715 9 +#HACK STRING EVAL +3.7355212569236755 4 +5.836455881595612 5 +10.896394848823547 9 +8.075075268745422 7 +4.78675901889801 5 +13.293394446372986 10 +0.3834933042526245 1 +9.162235260009766 9 +0.996394157409668 1 +7.327843904495239 8 +#HACK STRING EVAL +5.962847411632538 6 +3.7739017009735107 4 +10.254373610019684 9 +7.670405387878418 8 +8.660718858242035 8 +7.008784830570221 7 +7.727816820144653 8 +8.676700294017792 8 +2.418344020843506 2 +7.9378368854522705 6 +#HACK STRING EVAL +4.733837604522705 5 +9.318564534187317 10 +9.356670022010803 7 +4.540631353855133 5 +9.31334114074707 10 +9.537618696689606 9 +8.925869166851044 9 +6.562559485435486 5 +4.768107652664185 5 +9.429795503616333 8 +#HACK STRING EVAL +4.4323283433914185 5 +7.714688301086426 8 +7.258630275726318 6 +10.973442554473877 9 +6.18261182308197 5 +7.880877196788788 7 +6.055438697338104 5 +8.537951469421387 9 +7.5647547245025635 7 +3.670006215572357 4 +#HACK STRING EVAL +-0.4631376266479492 100 +-3.382357597351074 100 +-4.708723068237305 100 +8.355179488658905 11 +-3.0235681533813477 100 +8.69126296043396 12 +3.878988564014435 16 +0.3184947967529297 100 +-2.2480220794677734 100 +-1.8174934387207031 100 +#HACK STRING EVAL +5.560295462608337 6 +4.4286163449287415 5 +7.627099633216858 11 +10.06272840499878 10 +5.226018249988556 5 +9.436014354228973 16 +8.708190739154816 12 +8.302237808704376 12 +7.305310487747192 9 +8.870814323425293 8 +#HACK STRING EVAL +8.961800992488861 10 +7.835615396499634 6 +7.779029726982117 8 +4.235402524471283 5 +7.213650465011597 8 +10.339050829410553 9 +9.088867843151093 9 +7.408116161823273 8 +5.642811298370361 6 +6.221526920795441 6 +#HACK STRING EVAL +5.737524449825287 6 +7.054350852966309 7 +4.273497700691223 4 +7.436541140079498 8 +10.347003638744354 9 +9.813101172447205 8 +6.594050586223602 7 +7.684672057628632 8 +10.106456995010376 8 +2.6233807802200317 3 +#HACK STRING EVAL +6.6536043882369995 7 +5.534941554069519 5 +8.71265321969986 7 +1.1946840286254883 1 +8.120160698890686 7 +6.073153555393219 5 +4.2648215889930725 4 +7.784718751907349 6 +7.287018537521362 6 +1.2615447044372559 1 +#HACK STRING EVAL +7.4992693066596985 7 +3.22348290681839 3 +9.21939605474472 8 +6.225876152515411 6 +10.823611617088318 9 +7.872636079788208 8 +9.770297229290009 9 +6.724462270736694 7 +2.0980435609817505 2 +5.733666121959686 5 +#HACK STRING EVAL +4.794735372066498 5 +4.994202792644501 5 +8.73866856098175 7 +10.665687680244446 8 +12.132819414138794 9 +2.406223177909851 2 +12.70932126045227 10 +9.218336641788483 9 +8.550141215324402 8 +5.5698240995407104 6 +#HACK STRING EVAL +6.282139301300049 6 +3.8584097027778625 4 +2.7530354261398315 3 +3.8999165892601013 4 +8.630044221878052 9 +7.005427718162537 7 +6.436145544052124 5 +11.243283748626709 9 +8.745630621910095 9 +8.687362968921661 9 +#HACK STRING EVAL +7.90007871389389 8 +8.042057454586029 7 +5.777434408664703 6 +1.3310515880584717 1 +8.056971907615662 8 +5.344740509986877 4 +2.614309549331665 3 +6.71746689081192 6 +5.737132251262665 6 +4.782473623752594 4 +#HACK STRING EVAL +8.930620193481445 9 +3.31032133102417 3 +7.940674304962158 6 +7.393050849437714 7 +10.054099917411804 8 +12.794913232326508 10 +9.409365177154541 9 +7.011675119400024 7 +11.03419941663742 9 +5.784710764884949 6 +#HACK STRING EVAL +8.959876775741577 8 +9.020298421382904 8 +11.47550654411316 10 +7.637091100215912 8 +2.98943430185318 3 +7.942509174346924 6 +9.008321583271027 8 +4.763214349746704 4 +3.556677758693695 4 +5.7922863364219666 6 +#HACK STRING EVAL +5.16298520565033 4 +13.070879817008972 10 +9.989671051502228 8 +6.729265332221985 6 +11.179619789123535 9 +3.947337508201599 4 +0.9793047904968262 1 +5.699759304523468 6 +11.149385690689087 9 +9.775951027870178 9 +#HACK STRING EVAL +6.16756808757782 6 +10.194958925247192 8 +10.941422820091248 10 +3.7836004495620728 4 +11.648289680480957 9 +2.8915421962738037 3 +9.339996337890625 10 +5.102701425552368 4 +8.776802062988281 9 +8.697715163230896 9 +#HACK STRING EVAL +10.301258206367493 8 +9.514545261859894 8 +10.813766717910767 9 +5.458991050720215 6 +9.000311017036438 9 +9.26505184173584 10 +8.415939152240753 8 +10.599741458892822 9 +5.065022110939026 5 +7.756350755691528 8 +#HACK STRING EVAL +8.275232374668121 8 +2.893139660358429 3 +11.598932027816772 9 +4.270497441291809 4 +8.193299651145935 9 +8.531015396118164 9 +8.902573645114899 9 +9.287388324737549 8 +7.250800549983978 7 +12.003655672073364 9 +#HACK STRING EVAL +3.842432737350464 4 +6.006695985794067 5 +10.902550041675568 9 +8.035821557044983 7 +4.814881443977356 5 +13.390470027923584 10 +0.4314527213573456 1 +9.34487795829773 9 +1.0256820917129517 1 +7.394945740699768 8 +#HACK STRING EVAL +6.569110631942749 7 +3.7528374195098877 4 +10.258695363998413 9 +7.709716975688934 8 +8.745060443878174 8 +6.956442594528198 7 +7.650391697883606 8 +8.740313649177551 8 +2.4417892694473267 2 +8.01558542251587 6 +#HACK STRING EVAL +4.843487024307251 5 +9.251512110233307 10 +9.362451672554016 7 +4.516017973423004 5 +9.402168095111847 10 +9.52513301372528 9 +9.063587069511414 9 +6.543292760848999 5 +4.754206538200378 5 +9.496736764907837 8 +#HACK STRING EVAL +4.436246335506439 5 +7.712571024894714 8 +7.295897424221039 6 +10.780003726482391 9 +6.144953548908234 5 +7.988951086997986 7 +6.112201035022736 5 +8.704338192939758 9 +7.575714409351349 7 +3.771587550640106 4 +#HACK STRING EVAL +0.31778621673583984 100 +6.525563299655914 24 +5.1543973088264465 65 +8.303515315055847 51 +6.858564078807831 41 +8.672177076339722 50 +3.9259626269340515 45 +10.193282306194305 40 +-2.0925493240356445 100 +8.095625638961792 39 +#HACK STRING EVAL +5.592415034770966 7 +4.664132595062256 6 +7.499769628047943 9 +9.898514032363892 12 +5.338938474655151 9 +9.309739530086517 12 +8.740740478038788 11 +8.371590733528137 11 +7.163245439529419 10 +8.855569243431091 13 +#HACK STRING EVAL +9.471169531345367 11 +8.377021372318268 8 +7.828118205070496 8 +4.730342626571655 6 +7.3547675013542175 8 +10.818765580654144 9 +9.487009465694427 10 +7.212972044944763 8 +5.355174362659454 6 +6.2041016817092896 6 +#HACK STRING EVAL +5.691044211387634 6 +7.802906274795532 8 +3.5168673992156982 3 +7.533621430397034 8 +10.23910677433014 9 +9.1512051820755 7 +6.5727680921554565 7 +7.5947794914245605 8 +9.263620495796204 7 +2.7281141877174377 3 +#HACK STRING EVAL +6.648212909698486 7 +5.502921223640442 5 +8.69333815574646 7 +1.1839065551757812 1 +8.187583923339844 7 +6.137961983680725 5 +4.23045152425766 4 +7.939318060874939 6 +7.41776829957962 6 +1.2686573266983032 1 +#HACK STRING EVAL +7.492980420589447 7 +3.3738550543785095 3 +9.186606049537659 8 +6.27595317363739 6 +10.877623915672302 9 +7.9450541734695435 8 +9.749276101589203 9 +6.692711055278778 7 +2.096704423427582 2 +5.719252228736877 5 +#HACK STRING EVAL +4.87362939119339 5 +4.961513638496399 5 +8.87126100063324 7 +10.629716634750366 8 +12.176140546798706 9 +2.4573116302490234 2 +11.991995453834534 9 +9.427624821662903 9 +8.559147655963898 8 +5.775904655456543 6 +#HACK STRING EVAL +6.288851499557495 6 +4.107277572154999 4 +2.801826775074005 3 +3.9199097752571106 4 +8.634842336177826 9 +6.987921893596649 7 +6.36008620262146 5 +11.484338343143463 9 +8.683319509029388 9 +8.667238295078278 9 +#HACK STRING EVAL +7.805923640727997 8 +8.053959906101227 7 +5.829171717166901 6 +1.3194509744644165 1 +7.99535608291626 8 +5.317466497421265 4 +1.9453045129776 2 +6.681754946708679 6 +5.705694735050201 6 +4.804542720317841 4 +#HACK STRING EVAL +9.086811184883118 9 +3.230072319507599 3 +8.607045114040375 7 +7.403345346450806 7 +10.065696358680725 8 +12.865141153335571 10 +9.38029032945633 9 +7.047023296356201 7 +11.167766094207764 9 +5.7528626918792725 6 +#HACK STRING EVAL +8.925208508968353 8 +9.087477564811707 8 +11.663830518722534 10 +7.6803505420684814 8 +3.057560682296753 3 +7.945772290229797 6 +9.303220987319946 8 +4.769311428070068 4 +2.8834707736968994 3 +5.877671122550964 6 +#HACK STRING EVAL +5.228637456893921 4 +13.106784224510193 10 +10.011388421058655 8 +6.809486627578735 6 +11.281269431114197 9 +3.9158620834350586 4 +1.013548731803894 1 +5.7747756242752075 6 +11.93122923374176 10 +9.922957837581635 9 +#HACK STRING EVAL +6.31686931848526 6 +10.127385914325714 8 +11.066558361053467 10 +3.8692283034324646 4 +11.556978344917297 9 +2.909392476081848 3 +9.79418557882309 10 +5.069006681442261 4 +8.586906373500824 9 +8.383707702159882 9 +#HACK STRING EVAL +10.348942041397095 8 +9.543898284435272 8 +10.742013454437256 9 +5.513120055198669 6 +8.75621372461319 9 +9.629023671150208 10 +8.409048676490784 8 +10.609800696372986 9 +5.067638099193573 5 +7.516099154949188 8 +#HACK STRING EVAL +7.701353371143341 7 +2.8090460896492004 3 +11.583921074867249 9 +4.20162045955658 4 +7.7159184217453 8 +8.651747345924377 9 +8.698903679847717 9 +9.291249692440033 8 +7.361828804016113 7 +11.891748428344727 9 +#HACK STRING EVAL +3.912439525127411 4 +5.944341361522675 5 +10.855936825275421 9 +8.037688434123993 7 +4.764046549797058 5 +13.455838441848755 10 +0.4094744324684143 1 +9.454913437366486 9 +1.0149601697921753 1 +7.672622859477997 8 +#HACK STRING EVAL +6.512591183185577 7 +3.749338388442993 4 +10.31449282169342 9 +7.708499014377594 8 +8.698538303375244 8 +6.936611592769623 7 +7.761456191539764 8 +8.68586003780365 8 +2.4507886171340942 2 +8.014462232589722 6 +#HACK STRING EVAL +4.777271866798401 5 +9.495110869407654 10 +9.34801959991455 7 +4.601814448833466 5 +9.206101953983307 10 +9.448477506637573 9 +9.033104658126831 9 +6.568693280220032 5 +4.65021824836731 5 +9.424847602844238 8 +#HACK STRING EVAL +4.431134283542633 5 +7.754373908042908 8 +7.183567523956299 6 +10.896063327789307 9 +6.155987501144409 5 +8.100101709365845 7 +6.591293394565582 6 +8.619274199008942 9 +7.619318604469299 7 +3.7310428619384766 4 +#HACK STRING EVAL +-3.7503671646118164 100 +-6.669588088989258 100 +5.190404057502747 12 +8.24594646692276 23 +-6.310798645019531 100 +8.68351423740387 23 +3.890957772731781 19 +-2.968735694885254 100 +-5.535251617431641 100 +-5.104723930358887 100 +#HACK STRING EVAL +5.767999172210693 7 +4.666956305503845 6 +7.540254592895508 17 +10.105437159538269 10 +5.394420564174652 6 +9.313964366912842 16 +8.756088972091675 19 +8.188567996025085 18 +7.065285503864288 8 +8.961012363433838 9 +#HACK STRING EVAL +9.175539016723633 10 +8.526599526405334 7 +7.3231536746025085 8 +4.379340887069702 5 +6.859935522079468 7 +10.733378291130066 9 +9.13436895608902 9 +6.825154006481171 7 +5.744129180908203 6 +6.170496046543121 7 +#HACK STRING EVAL +5.781615495681763 6 +7.060114324092865 7 +4.17647647857666 4 +7.664764165878296 8 +10.336327850818634 9 +9.639709830284119 8 +6.792256295681 7 +7.725595772266388 8 +10.085983753204346 8 +1.8957409858703613 2 +#HACK STRING EVAL +6.725794315338135 7 +5.495726764202118 5 +8.59859585762024 7 +1.1628730297088623 1 +8.190592408180237 7 +6.037627458572388 5 +4.28792130947113 4 +7.8533666133880615 6 +7.288529336452484 6 +1.3191734552383423 1 +#HACK STRING EVAL +7.5782501101493835 7 +3.393980383872986 3 +9.251440823078156 8 +6.307782053947449 6 +10.824677884578705 9 +7.9978508949279785 8 +9.838298857212067 9 +6.797225058078766 7 +2.0683290362358093 2 +5.712627112865448 5 +#HACK STRING EVAL +4.735698401927948 5 +4.971351742744446 5 +8.639134109020233 7 +10.519837260246277 8 +12.586857914924622 10 +2.392622470855713 2 +12.518879175186157 10 +8.542624592781067 8 +8.683528900146484 8 +4.845826983451843 5 +#HACK STRING EVAL +6.3389886021614075 6 +3.873749017715454 4 +2.635150730609894 3 +3.88975065946579 4 +8.556178033351898 9 +6.973714470863342 7 +6.361687064170837 5 +11.427106976509094 9 +8.66763025522232 9 +8.644666850566864 9 +#HACK STRING EVAL +7.798373222351074 8 +8.052430748939514 7 +5.732905447483063 6 +1.3335161209106445 1 +8.003287374973297 8 +5.3025078773498535 4 +1.9311631917953491 2 +6.693082332611084 6 +5.666674435138702 6 +4.758456468582153 4 +#HACK STRING EVAL +8.955053210258484 9 +3.3723626732826233 3 +7.925347805023193 6 +7.37316632270813 7 +9.74011480808258 8 +12.83076423406601 10 +9.412858486175537 9 +6.961702823638916 7 +10.977873086929321 9 +5.79434061050415 6 +#HACK STRING EVAL +9.041838526725769 8 +9.057227849960327 8 +11.450349569320679 10 +7.667618155479431 8 +2.939761996269226 3 +7.924565076828003 6 +9.097343504428864 8 +4.775996267795563 4 +3.483647346496582 4 +5.797825396060944 6 +#HACK STRING EVAL +5.255456924438477 4 +13.147987365722656 10 +10.032495737075806 8 +6.676841616630554 6 +11.167320787906647 9 +3.97529798746109 4 +0.9535502791404724 1 +5.795343518257141 6 +11.143865168094635 9 +9.71838653087616 9 +#HACK STRING EVAL +6.1599041223526 6 +10.321870565414429 8 +10.78938603401184 10 +3.7759790420532227 4 +11.747192740440369 9 +2.7390143275260925 3 +9.521189570426941 10 +5.0743478536605835 4 +8.691401600837708 9 +8.56460976600647 9 +#HACK STRING EVAL +10.359325051307678 8 +9.579071760177612 8 +10.75034111738205 9 +5.472748756408691 6 +8.835463285446167 9 +9.223086416721344 10 +8.411719679832458 8 +10.637408018112183 9 +5.098482728004456 5 +7.540639221668243 8 +#HACK STRING EVAL +8.284957528114319 8 +2.909843146800995 3 +11.498991966247559 9 +4.314784348011017 4 +7.719284772872925 8 +8.474148571491241 9 +9.03158175945282 9 +9.24748682975769 8 +7.289325773715973 7 +11.988104462623596 9 +#HACK STRING EVAL +3.805665910243988 4 +5.829372525215149 5 +10.941343545913696 9 +8.106742084026337 7 +4.8556849360466 5 +13.241164565086365 10 +0.44493916630744934 1 +9.30172461271286 9 +1.0235121250152588 1 +7.398443698883057 8 +#HACK STRING EVAL +6.6572558879852295 7 +3.8123266100883484 4 +10.238943040370941 9 +7.86910218000412 8 +8.775851726531982 8 +7.025744557380676 7 +7.79372102022171 8 +8.661433339118958 8 +2.441502332687378 2 +7.951806902885437 6 +#HACK STRING EVAL +4.8314109444618225 5 +9.437495291233063 10 +9.269285559654236 7 +4.433978378772736 5 +9.326415419578552 10 +9.517026364803314 9 +8.995151281356812 9 +6.490075945854187 5 +4.8496845960617065 5 +9.587450742721558 8 +#HACK STRING EVAL +4.361202418804169 5 +7.62955641746521 8 +7.222605049610138 6 +10.286738157272339 8 +6.158017218112946 5 +7.950848698616028 7 +6.088044464588165 5 +8.535565197467804 9 +7.499076068401337 7 +3.749497354030609 4 +#HACK STRING EVAL +-3.7503671646118164 100 +6.683683753013611 10 +-7.995953559875488 100 +-4.92095947265625 100 +-6.310798645019531 100 +-4.496591567993164 100 +-9.295823574066162 100 +-2.968735694885254 100 +-5.535251617431641 100 +8.06235384941101 20 +#HACK STRING EVAL +5.819346606731415 6 +4.804377555847168 5 +8.019149482250214 8 +9.892074763774872 9 +5.562873363494873 6 +9.565993130207062 10 +9.04113894701004 9 +8.216477274894714 8 +7.279657661914825 8 +9.154029846191406 9 +#HACK STRING EVAL +9.545878469944 10 +8.607473611831665 7 +8.140395402908325 8 +4.611998081207275 5 +7.134553074836731 7 +10.582031488418579 9 +9.139855563640594 9 +6.840529203414917 7 +5.831222176551819 6 +6.463957965373993 6 +#HACK STRING EVAL +5.8273738622665405 6 +7.032221734523773 7 +3.521279811859131 3 +7.817870318889618 8 +10.238489091396332 9 +9.0858895778656 7 +6.871851921081543 7 +7.789297819137573 8 +9.246049642562866 7 +1.931517481803894 2 +#HACK STRING EVAL +6.832900762557983 7 +5.5143356919288635 5 +8.543055653572083 7 +1.2191656827926636 1 +8.125712215900421 7 +6.072571039199829 5 +4.208197236061096 4 +7.952274918556213 6 +7.358014762401581 6 +1.3228609561920166 1 +#HACK STRING EVAL +7.579061686992645 7 +3.3794658184051514 3 +9.282795190811157 8 +6.263615906238556 6 +10.757392883300781 9 +7.989158272743225 8 +10.474443078041077 10 +6.784158229827881 7 +2.086500644683838 2 +5.750377058982849 5 +#HACK STRING EVAL +4.862272202968597 5 +4.9596264362335205 5 +8.702011704444885 7 +10.70015573501587 8 +12.54947829246521 10 +2.4242825508117676 2 +12.683998823165894 10 +9.314911127090454 9 +8.58104956150055 8 +4.8440922498703 5 +#HACK STRING EVAL +6.300704717636108 6 +3.9728944301605225 4 +2.7162012457847595 3 +3.911979377269745 4 +8.688069820404053 9 +6.926848649978638 7 +6.387660026550293 5 +11.43892627954483 9 +8.756018936634064 9 +9.525359332561493 10 +#HACK STRING EVAL +7.883832931518555 8 +7.959962546825409 7 +5.710424184799194 6 +1.3243162631988525 1 +8.04818570613861 8 +5.306087255477905 4 +1.931667983531952 2 +6.716375172138214 6 +5.625905632972717 6 +4.7644699811935425 4 +#HACK STRING EVAL +8.917754292488098 9 +3.3362773656845093 3 +7.99504280090332 6 +7.405434310436249 7 +9.88921594619751 8 +12.856024503707886 10 +9.416145145893097 9 +6.958747506141663 7 +11.032432675361633 9 +5.588223814964294 6 +#HACK STRING EVAL +8.93117368221283 8 +9.01198935508728 8 +11.28940337896347 10 +7.670053958892822 8 +2.9177671670913696 3 +7.869323968887329 6 +8.968942880630493 8 +4.761840283870697 4 +3.4364015460014343 4 +5.7541210651397705 6 +#HACK STRING EVAL +5.164194226264954 4 +13.04754775762558 10 +9.984059572219849 8 +6.747242331504822 6 +10.927258551120758 9 +3.990667462348938 4 +0.9488641619682312 1 +5.808480978012085 6 +11.695778369903564 10 +9.84803694486618 9 +#HACK STRING EVAL +6.083542764186859 6 +10.188265919685364 8 +10.927263021469116 10 +3.7588252425193787 4 +11.625951528549194 9 +2.7659069299697876 3 +9.669820308685303 10 +5.058640956878662 4 +8.706737697124481 9 +8.51842451095581 9 +#HACK STRING EVAL +10.267734289169312 8 +9.616522252559662 8 +10.721719563007355 9 +5.358271956443787 6 +8.916476130485535 9 +9.397712469100952 10 +8.372869193553925 8 +10.481555342674255 9 +5.034985661506653 5 +7.633592963218689 8 +#HACK STRING EVAL +8.257639646530151 8 +2.881767988204956 3 +11.656640231609344 9 +4.234393835067749 4 +7.7316412925720215 8 +8.396616101264954 9 +8.791178524494171 9 +9.207283020019531 8 +7.329791069030762 7 +11.94670820236206 9 +#HACK STRING EVAL +3.7711241841316223 4 +5.852321267127991 5 +10.913367807865143 9 +8.054116547107697 7 +4.850949585437775 5 +13.29242718219757 10 +0.4322148859500885 1 +9.253706395626068 9 +1.0066921710968018 1 +7.45316219329834 8 +#HACK STRING EVAL +5.946453630924225 6 +3.742201566696167 4 +10.255728602409363 9 +7.673747956752777 8 +8.758006930351257 8 +6.919146955013275 7 +7.789984226226807 8 +8.814360797405243 8 +2.442374587059021 2 +8.023592233657837 6 +#HACK STRING EVAL +4.7665517926216125 5 +9.495097279548645 10 +9.302823543548584 7 +4.563109636306763 5 +9.35026240348816 10 +9.49923586845398 9 +9.039598166942596 9 +6.52428925037384 5 +4.7161818742752075 5 +9.46393883228302 8 +#HACK STRING EVAL +4.416747808456421 5 +7.671242654323578 8 +6.677221298217773 5 +10.823423087596893 9 +6.152508974075317 5 +7.966321766376495 7 +6.121146976947784 5 +8.516756057739258 9 +7.56088799238205 7 +3.845704436302185 4 +#HACK STRING EVAL +9.42851835489273 18 +-6.669588088989258 100 +-7.995953559875488 100 +-4.92095947265625 100 +-6.310798645019531 100 +-4.496591567993164 100 +-9.295823574066162 100 +-2.968735694885254 100 +-5.535251617431641 100 +-5.104723930358887 100 +#HACK STRING EVAL +5.550080120563507 17 +4.412675559520721 17 +7.477856636047363 27 +10.072757124900818 12 +5.275825500488281 7 +9.310020387172699 26 +8.590070068836212 28 +8.097746551036835 28 +6.953436493873596 10 +8.868224143981934 10 +#HACK STRING EVAL +9.231639802455902 10 +8.329555451869965 8 +7.844920873641968 9 +4.383041203022003 5 +6.987540602684021 7 +10.197158575057983 8 +9.624447166919708 11 +7.406171023845673 9 +5.737441897392273 7 +6.4715511202812195 7 +#HACK STRING EVAL +5.60809725522995 6 +7.662423372268677 8 +4.320146083831787 4 +7.621774792671204 8 +10.387636661529541 9 +8.966591596603394 7 +6.743286311626434 7 +7.506706774234772 8 +9.47699385881424 8 +2.6546404361724854 3 +#HACK STRING EVAL +6.783365368843079 7 +5.523658871650696 5 +8.59656149148941 7 +1.165936827659607 1 +8.187030255794525 7 +6.240353226661682 5 +4.218744456768036 4 +7.865852236747742 6 +7.271162986755371 6 +1.2723803520202637 1 +#HACK STRING EVAL +7.522215783596039 7 +3.442526340484619 3 +9.17734694480896 8 +6.260113954544067 6 +10.906949758529663 9 +7.97680938243866 8 +9.778206646442413 9 +6.7647839188575745 7 +2.0173386335372925 2 +5.7865684032440186 5 +#HACK STRING EVAL +4.90592086315155 5 +5.011420249938965 5 +8.726033627986908 7 +10.676520824432373 8 +12.077523469924927 9 +2.4032742977142334 2 +11.970990180969238 9 +8.598079562187195 8 +8.644791185855865 8 +4.8467918038368225 5 +#HACK STRING EVAL +6.2508960366249084 6 +4.123034834861755 4 +2.8337900638580322 3 +3.948044180870056 4 +8.718375504016876 9 +6.977458357810974 7 +6.3972169160842896 5 +11.448109805583954 9 +8.833882987499237 9 +9.441977798938751 10 +#HACK STRING EVAL +7.845255076885223 8 +7.961222052574158 7 +5.845944881439209 6 +1.3311727046966553 1 +8.016471922397614 8 +5.370995044708252 4 +1.9814203381538391 2 +6.720756530761719 6 +5.833879351615906 6 +4.786039471626282 4 +#HACK STRING EVAL +9.093159556388855 9 +3.2457783818244934 3 +7.9258644580841064 6 +7.399986684322357 7 +10.117446422576904 8 +12.91323983669281 10 +9.376475095748901 9 +7.048648238182068 7 +10.971034288406372 9 +5.490185439586639 6 +#HACK STRING EVAL +8.871527552604675 8 +9.089475572109222 8 +11.517087817192078 10 +7.571069180965424 8 +3.0352758169174194 3 +7.942550182342529 6 +9.16678535938263 8 +4.80262416601181 4 +2.879283308982849 3 +5.8214550614356995 6 +#HACK STRING EVAL +5.146155118942261 4 +13.120462417602539 10 +10.009042739868164 8 +6.85128778219223 6 +11.122773885726929 9 +4.01359498500824 4 +0.9517877697944641 1 +5.751624345779419 6 +11.933196663856506 10 +10.034156501293182 9 +#HACK STRING EVAL +6.2440996170043945 6 +10.119600355625153 8 +11.017512559890747 10 +3.820905327796936 4 +11.550909161567688 9 +2.8355214595794678 3 +9.69153779745102 10 +5.088356256484985 4 +8.750413715839386 9 +8.55090320110321 9 +#HACK STRING EVAL +10.278148651123047 8 +9.636350154876709 8 +10.829870164394379 9 +5.572406530380249 6 +8.985534429550171 9 +9.563805997371674 10 +8.423134505748749 8 +10.480247557163239 9 +5.073349475860596 5 +7.797201216220856 8 +#HACK STRING EVAL +8.413505971431732 8 +2.9104233980178833 3 +11.553630650043488 9 +4.260732114315033 4 +7.699001371860504 8 +8.575535893440247 9 +8.901431798934937 9 +9.17127537727356 8 +7.421786248683929 7 +11.948167085647583 9 +#HACK STRING EVAL +3.8735731840133667 4 +6.002425909042358 5 +10.951793372631073 9 +8.071584582328796 7 +4.9632408618927 5 +13.420955777168274 10 +0.4389267563819885 1 +9.396481454372406 9 +1.0300474166870117 1 +7.679368674755096 8 +#HACK STRING EVAL +5.924594402313232 6 +3.916688859462738 4 +10.320810437202454 9 +7.730223298072815 8 +8.935237169265747 8 +6.950528264045715 7 +7.764599978923798 8 +8.713307559490204 8 +2.457232356071472 2 +7.9826061725616455 6 +#HACK STRING EVAL +4.795742213726044 5 +9.422223210334778 10 +9.41665530204773 7 +4.591275274753571 5 +9.384173929691315 10 +9.573889374732971 9 +9.126929640769958 9 +6.586616516113281 5 +4.841431975364685 5 +9.611409366130829 8 +#HACK STRING EVAL +4.46467387676239 5 +7.715214431285858 8 +6.674523115158081 5 +10.885679364204407 9 +6.229204058647156 5 +8.03596556186676 7 +6.123936176300049 5 +8.703723549842834 9 +7.654842138290405 7 +3.770057797431946 4 +#HACK STRING EVAL +-3.7503671646118164 100 +-6.669588088989258 100 +-7.995953559875488 100 +-4.92095947265625 100 +-6.310798645019531 100 +-4.496591567993164 100 +-9.295823574066162 100 +-2.968735694885254 100 +-5.535251617431641 100 +-5.104723930358887 100 +#HACK STRING EVAL +5.763805866241455 17 +4.487055063247681 14 +7.55924129486084 10 +9.823716521263123 14 +5.237846612930298 10 +9.469707131385803 13 +8.60653668642044 11 +8.255623817443848 11 +7.015950083732605 11 +8.974082291126251 13 +#HACK STRING EVAL +9.385064661502838 10 +8.138331472873688 8 +7.631605505943298 8 +4.479820430278778 5 +7.046051442623138 7 +10.33671772480011 9 +9.397733628749847 10 +7.119406461715698 8 +5.264481484889984 6 +6.0132352113723755 6 +#HACK STRING EVAL +5.715270042419434 6 +7.807390093803406 8 +4.284856200218201 4 +7.765324413776398 8 +10.237981140613556 9 +9.650312542915344 8 +6.882023274898529 7 +7.592922389507294 8 +9.380728721618652 7 +1.8937543630599976 2 +#HACK STRING EVAL +6.742684185504913 7 +5.532135009765625 5 +8.59825885295868 7 +1.1849021911621094 1 +8.226038098335266 7 +5.3535027503967285 4 +4.299096882343292 4 +7.8352861404418945 6 +7.241643071174622 6 +1.3367478847503662 1 +#HACK STRING EVAL +7.5349081158638 7 +3.2966320514678955 3 +9.223799586296082 8 +6.296208620071411 6 +10.810195565223694 9 +8.025556087493896 8 +9.818405151367188 9 +6.7720513343811035 7 +2.11952805519104 2 +5.790731191635132 5 +#HACK STRING EVAL +4.905860424041748 5 +5.012655735015869 5 +8.745783567428589 7 +10.746114611625671 8 +12.047107934951782 9 +2.421426773071289 2 +12.802175879478455 10 +8.589167177677155 8 +8.599439144134521 8 +4.845293045043945 5 +#HACK STRING EVAL +6.14794796705246 6 +3.924871861934662 4 +2.7396640181541443 3 +3.889845609664917 4 +8.572834134101868 9 +6.976114988327026 7 +6.377196311950684 5 +11.13130098581314 9 +8.624421238899231 9 +8.68456518650055 9 +#HACK STRING EVAL +7.961768090724945 8 +7.880276918411255 7 +5.7162041664123535 6 +1.3266607522964478 1 +7.997768580913544 8 +5.412989616394043 4 +1.9323660731315613 2 +6.774179935455322 6 +5.610076308250427 6 +4.812200129032135 4 +#HACK STRING EVAL +8.980389475822449 9 +3.3831422328948975 3 +7.966309070587158 6 +7.434051275253296 7 +9.838586211204529 8 +12.86219584941864 10 +9.425139248371124 9 +7.0091612339019775 7 +10.896631598472595 9 +5.623668849468231 6 +#HACK STRING EVAL +9.038959681987762 8 +9.03045928478241 8 +11.310941398143768 10 +7.673098683357239 8 +3.0278974771499634 3 +7.95389711856842 6 +9.05371379852295 8 +4.789311468601227 4 +3.543650984764099 4 +5.751144647598267 6 +#HACK STRING EVAL +5.242049813270569 4 +13.242424011230469 10 +9.89390516281128 8 +6.75080806016922 6 +11.25408798456192 9 +3.954336404800415 4 +0.9574837684631348 1 +5.632983148097992 6 +11.182879090309143 9 +9.749130070209503 9 +#HACK STRING EVAL +6.289591729640961 6 +10.332736372947693 8 +10.888150036334991 10 +3.762923240661621 4 +11.757488250732422 9 +2.8076146245002747 3 +9.650723338127136 10 +5.0681562423706055 4 +8.732304394245148 9 +8.562131524085999 9 +#HACK STRING EVAL +10.807774841785431 9 +9.540550708770752 8 +10.974451661109924 9 +5.4373146295547485 6 +8.81661868095398 9 +9.653258681297302 10 +8.554339528083801 8 +10.45610797405243 9 +5.156678140163422 5 +7.591727316379547 8 +#HACK STRING EVAL +8.289832711219788 8 +2.943417191505432 3 +11.48240315914154 9 +4.314955711364746 4 +8.377607583999634 9 +8.57163006067276 9 +8.89093792438507 9 +9.381282925605774 8 +7.31221067905426 7 +12.573387622833252 10 +#HACK STRING EVAL +3.9085779190063477 4 +5.914822041988373 5 +10.79609215259552 9 +7.967034637928009 7 +4.8820735812187195 5 +13.360183715820312 10 +0.46174681186676025 1 +9.338318526744843 9 +1.0449638366699219 1 +7.604488968849182 8 +#HACK STRING EVAL +5.939280807971954 6 +3.7368022203445435 4 +10.171412467956543 9 +7.792130827903748 8 +8.881611168384552 8 +7.063364803791046 7 +7.879661560058594 8 +8.664407074451447 8 +2.447699546813965 2 +7.976495027542114 6 +#HACK STRING EVAL +4.868215441703796 5 +9.547277629375458 10 +9.216423392295837 7 +4.568718910217285 5 +9.231430053710938 10 +9.572161197662354 9 +8.907981634140015 9 +6.516532063484192 5 +4.8455140590667725 5 +9.741968035697937 8 +#HACK STRING EVAL +4.3997692465782166 5 +7.698659300804138 8 +7.268149435520172 6 +10.779749989509583 9 +6.14505273103714 5 +8.004122257232666 7 +6.1490079164505005 5 +8.684592127799988 9 +7.602573573589325 7 +3.736556649208069 4 diff --git a/tests/test_analysis_code.py b/tests/test_analysis_code.py new file mode 100644 index 0000000..c69b828 --- /dev/null +++ b/tests/test_analysis_code.py @@ -0,0 +1,61 @@ +import sys +from datetime import datetime +import logging +import copy +import numpy as np +from mdp_playground.envs.rl_toy_env import RLToyEnv +import unittest + + +log_filename = ( + "/tmp/test_analysis_code_" + + datetime.today().strftime("%m.%d.%Y_%I:%M:%S_%f") + + ".log" +) # TODO Make a directoy 'log/' and store there. + + +class TestAnalysisCode(unittest.TestCase): + def test_mdpp_to_cave(self): + """ """ + print("\033[32;1;4mTEST_MDPP_TO_CAVE\033[0m") + + from mdp_playground.analysis import MDPP_Analysis + # Set dir_name to the location where the CSV files from running an experiment were saved + dir_name = 'tests/files/mdpp_12744267_SAC_target_radius/' + # Set exp_name to the name that was given to the experiment when running it + exp_name = 'sac_move_to_a_point_target_radius' + # Set the following to True to save PDFs of plots that you generate below + save_fig = True + + + from cave.cavefacade import CAVE + from mdp_playground.analysis.mdpp_to_cave import MDPPToCave + import os + + # The converted mdpp csvs will be stored in output_dir + output_dir = "/tmp/mdpp_to_cave" + mdpp_cave = MDPPToCave() + + cave = mdpp_cave.to_CAVE_object(dir_name, exp_name, output_dir, overwrite=True) + + configs_json_line_1 = '[[0, 0, 0], {"target_radius": 0.05}, {"model_based_pick": false}]' + + with open(output_dir + "/" + exp_name + "/configs.json") as fh: + l1 = fh.readline()[:-1] # Ignore the \n at the end + assert l1 == configs_json_line_1 + + + configspace_json_line_7 = '"default": 0.525,' + + with open(output_dir + "/" + exp_name + "/configspace.json") as fh: + for i in range(7): + l = fh.readline() + assert l.strip() == configspace_json_line_7 + + + results_json_line_2 = '[[0, 0, 1], 20000, {"submitted": 1.1, "started": 1.2, "finished": 2.1}, {"loss": -7.261020890995861, "info": {}}, null]' + + with open(output_dir + "/" + exp_name + "/results.json") as fh: + for i in range(2): + l = fh.readline() + assert l.strip() == results_json_line_2 diff --git a/tests/test_run_experiments.py b/tests/test_run_experiments.py index 9270084..03f3413 100644 --- a/tests/test_run_experiments.py +++ b/tests/test_run_experiments.py @@ -8,7 +8,7 @@ from datetime import datetime log_filename = ( - "/tmp/test_mdp_playground_" + "/tmp/test_run_experiments_" + datetime.today().strftime("%m.%d.%Y_%I:%M:%S_%f") + ".log" ) From 241542ec9842e195efccdfa09e648157d78024ff Mon Sep 17 00:00:00 2001 From: Raghu Rajan Date: Wed, 6 Oct 2021 22:56:05 +0200 Subject: [PATCH 18/22] Try to fix failing tests --- .github/workflows/gh-test.yml | 2 +- setup.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/gh-test.yml b/.github/workflows/gh-test.yml index 1dd0c33..5881171 100644 --- a/.github/workflows/gh-test.yml +++ b/.github/workflows/gh-test.yml @@ -24,7 +24,7 @@ jobs: run: | python -m pip install --upgrade pip pip install flake8 pytest pytest-cov setuptools numpy - pip install -e .[extras_disc] + pip install -e .[extras_disc,hpo_analysis_require] pip install ray[rllib,debug]==0.7.3 pip install tensorflow==1.13.0rc1 - name: Lint with flake8 diff --git a/setup.py b/setup.py index ea5eb26..f6897b7 100644 --- a/setup.py +++ b/setup.py @@ -110,6 +110,7 @@ "extras": extras_require, "extras_disc": extras_require_disc, "extras_cont": extras_require_cont, + "hpo_analysis": hpo_analysis_require, }, entry_points={ "console_scripts": """ From b0294bd0b06a4c93c3d88d1261591d86e1e07630 Mon Sep 17 00:00:00 2001 From: Raghu Rajan Date: Wed, 6 Oct 2021 22:56:40 +0200 Subject: [PATCH 19/22] small bug --- .github/workflows/gh-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gh-test.yml b/.github/workflows/gh-test.yml index 5881171..0c7eaea 100644 --- a/.github/workflows/gh-test.yml +++ b/.github/workflows/gh-test.yml @@ -24,7 +24,7 @@ jobs: run: | python -m pip install --upgrade pip pip install flake8 pytest pytest-cov setuptools numpy - pip install -e .[extras_disc,hpo_analysis_require] + pip install -e .[extras_disc,hpo_analysis] pip install ray[rllib,debug]==0.7.3 pip install tensorflow==1.13.0rc1 - name: Lint with flake8 From 305e33ac2af80ae9e6644bf48ff7d63c9b107129 Mon Sep 17 00:00:00 2001 From: Raghu Rajan Date: Wed, 6 Oct 2021 23:13:14 +0200 Subject: [PATCH 20/22] Update code coverage to exclude example.py --- .coveragerc | 2 ++ setup.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 .coveragerc diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000..3f863e2 --- /dev/null +++ b/.coveragerc @@ -0,0 +1,2 @@ +[run] +omit = example.py diff --git a/setup.py b/setup.py index f6897b7..299dd70 100644 --- a/setup.py +++ b/setup.py @@ -52,7 +52,7 @@ ] hpo_analysis_require = [ - 'cave==1.4.0', + 'cave>=1.4.0', ] AUTHORS = ( From aad30709695afec1412dabe44420692c90642516 Mon Sep 17 00:00:00 2001 From: Raghu Rajan Date: Wed, 6 Oct 2021 23:21:12 +0200 Subject: [PATCH 21/22] Disable CAVE tests --- .github/workflows/gh-test.yml | 2 +- tests/test_analysis_code.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/gh-test.yml b/.github/workflows/gh-test.yml index 0c7eaea..1dd0c33 100644 --- a/.github/workflows/gh-test.yml +++ b/.github/workflows/gh-test.yml @@ -24,7 +24,7 @@ jobs: run: | python -m pip install --upgrade pip pip install flake8 pytest pytest-cov setuptools numpy - pip install -e .[extras_disc,hpo_analysis] + pip install -e .[extras_disc] pip install ray[rllib,debug]==0.7.3 pip install tensorflow==1.13.0rc1 - name: Lint with flake8 diff --git a/tests/test_analysis_code.py b/tests/test_analysis_code.py index c69b828..1232170 100644 --- a/tests/test_analysis_code.py +++ b/tests/test_analysis_code.py @@ -15,6 +15,8 @@ class TestAnalysisCode(unittest.TestCase): + + @pytest.mark.skip(reason="CAVE dependencies throw ImportError: cannot import name 'StatusType'") def test_mdpp_to_cave(self): """ """ print("\033[32;1;4mTEST_MDPP_TO_CAVE\033[0m") From 1458d226439b2db5861091761011e9e740021df9 Mon Sep 17 00:00:00 2001 From: Raghu Rajan Date: Wed, 6 Oct 2021 23:25:37 +0200 Subject: [PATCH 22/22] Fix tests --- tests/test_analysis_code.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_analysis_code.py b/tests/test_analysis_code.py index 1232170..4b46f06 100644 --- a/tests/test_analysis_code.py +++ b/tests/test_analysis_code.py @@ -5,6 +5,7 @@ import numpy as np from mdp_playground.envs.rl_toy_env import RLToyEnv import unittest +import pytest log_filename = (