diff --git a/vivarium/experimental/notebooks/braitenberg_selective_sensing.ipynb b/vivarium/experimental/notebooks/braitenberg_selective_sensing.ipynb new file mode 100644 index 0000000..4b6853a --- /dev/null +++ b/vivarium/experimental/notebooks/braitenberg_selective_sensing.ipynb @@ -0,0 +1,1374 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Quick tutorial to explain how to create a environment with braitenberg vehicles equiped with selective sensors (still a draft so comments of the notebook won't be complete yet)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "import logging as lg\n", + "\n", + "from enum import Enum\n", + "from functools import partial\n", + "from typing import Tuple\n", + "\n", + "import jax\n", + "import numpy as np\n", + "import jax.numpy as jnp\n", + "import matplotlib.colors as mcolors\n", + "\n", + "from jax import vmap, jit\n", + "from jax import random, ops, lax\n", + "\n", + "from flax import struct\n", + "from jax_md.rigid_body import RigidBody\n", + "from jax_md import simulate \n", + "from jax_md import space, rigid_body, partition, quantity\n", + "\n", + "from vivarium.experimental.environments.utils import normal, distance \n", + "from vivarium.experimental.environments.base_env import BaseState, BaseEnv\n", + "from vivarium.experimental.environments.physics_engine import total_collision_energy, friction_force, dynamics_fn\n", + "from vivarium.experimental.environments.braitenberg.simple import relative_position, proximity_map, sensor_fn, sensor\n", + "from vivarium.experimental.environments.braitenberg.simple import Behaviors, behavior_to_params, linear_behavior\n", + "from vivarium.experimental.environments.braitenberg.simple import lr_2_fwd_rot, fwd_rot_2_lr, motor_command\n", + "from vivarium.experimental.environments.braitenberg.simple import braintenberg_force_fn" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# Used for jax.debug.breakpoint in a jupyter notebook\n", + "class FakeStdin:\n", + " def readline(self):\n", + " return input()\n", + " \n", + "# Usage : \n", + "# jax.debug.breakpoint(backend=\"cli\", stdin=FakeStdin())\n", + "\n", + "# See this issue : https://github.com/google/jax/issues/11880" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Create the classes and helper functions" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Add entity sensed type as a field in entities + sensed in agents. The agents sense the \"sensed type\" of the entities. In our case, there will be preys, predators, ressources and poison." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "### Define the constants and the classes of the environment to store its state ###\n", + "SPACE_NDIMS = 2\n", + "\n", + "class EntityType(Enum):\n", + " AGENT = 0\n", + " OBJECT = 1\n", + "\n", + "# Already incorporates position, momentum, force, mass and velocity\n", + "@struct.dataclass\n", + "class EntityState(simulate.NVEState):\n", + " entity_type: jnp.array\n", + " ent_subtype: jnp.array\n", + " entity_idx: jnp.array\n", + " diameter: jnp.array\n", + " friction: jnp.array\n", + " exists: jnp.array\n", + " \n", + "@struct.dataclass\n", + "class ParticleState:\n", + " ent_idx: jnp.array\n", + " color: jnp.array\n", + "\n", + "@struct.dataclass\n", + "class AgentState(ParticleState):\n", + " prox: jnp.array\n", + " motor: jnp.array\n", + " proximity_map_dist: jnp.array\n", + " proximity_map_theta: jnp.array\n", + " behavior: jnp.array\n", + " params: jnp.array\n", + " sensed: jnp.array\n", + " wheel_diameter: jnp.array\n", + " speed_mul: jnp.array\n", + " max_speed: jnp.array\n", + " theta_mul: jnp.array \n", + " proxs_dist_max: jnp.array\n", + " proxs_cos_min: jnp.array\n", + "\n", + "@struct.dataclass\n", + "class ObjectState(ParticleState):\n", + " pass\n", + "\n", + "@struct.dataclass\n", + "class State(BaseState):\n", + " max_agents: jnp.int32\n", + " max_objects: jnp.int32\n", + " neighbor_radius: jnp.float32\n", + " dt: jnp.float32 # Give a more explicit name\n", + " collision_alpha: jnp.float32\n", + " collision_eps: jnp.float32\n", + " ent_sub_types: dict\n", + " entities: EntityState\n", + " agents: AgentState\n", + " objects: ObjectState " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Define get_relative_displacement" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "# TODO : Should refactor the function to split the returns\n", + "def get_relative_displacement(state, agents_neighs_idx, displacement_fn):\n", + " \"\"\"Get all infos relative to distance and orientation between all agents and their neighbors\n", + "\n", + " :param state: state\n", + " :param agents_neighs_idx: idx all agents neighbors\n", + " :param displacement_fn: jax md function enabling to know the distance between points\n", + " :return: distance array, angles array, distance map for all agents, angles map for all agents\n", + " \"\"\"\n", + " body = state.entities.position\n", + " senders, receivers = agents_neighs_idx\n", + " Ra = body.center[senders]\n", + " Rb = body.center[receivers]\n", + " dR = - space.map_bond(displacement_fn)(Ra, Rb) # Looks like it should be opposite, but don't understand why\n", + "\n", + " dist, theta = proximity_map(dR, body.orientation[senders])\n", + " proximity_map_dist = jnp.zeros((state.agents.ent_idx.shape[0], state.entities.entity_idx.shape[0]))\n", + " proximity_map_dist = proximity_map_dist.at[senders, receivers].set(dist)\n", + " proximity_map_theta = jnp.zeros((state.agents.ent_idx.shape[0], state.entities.entity_idx.shape[0]))\n", + " proximity_map_theta = proximity_map_theta.at[senders, receivers].set(theta)\n", + " return dist, theta, proximity_map_dist, proximity_map_theta" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "to compute motors, only use linear behaviors (don't vmap it) because we vmap the functions to compute agents proxiemters and motors at a higher level \n" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "def linear_behavior(proxs, params):\n", + " \"\"\"Compute the activation of motors with a linear combination of proximeters and parameters\n", + "\n", + " :param proxs: proximeter values of an agent\n", + " :param params: parameters of an agent (mapping proxs to motor values)\n", + " :return: motor values\n", + " \"\"\"\n", + " return params.dot(jnp.hstack((proxs, 1.)))\n", + "\n", + "def compute_motor(proxs, params, behaviors, motors):\n", + " \"\"\"Compute new motor values. If behavior is manual, keep same motor values. Else, compute new values with proximeters and params.\n", + "\n", + " :param proxs: proximeters of all agents\n", + " :param params: parameters mapping proximeters to new motor values\n", + " :param behaviors: array of behaviors\n", + " :param motors: current motor values\n", + " :return: new motor values\n", + " \"\"\"\n", + " manual = jnp.where(behaviors == Behaviors.MANUAL.value, 1, 0)\n", + " manual_mask = manual\n", + " linear_motor_values = linear_behavior(proxs, params)\n", + " motor_values = linear_motor_values * (1 - manual_mask) + motors * manual_mask\n", + " return motor_values" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1 : Add functions to compute the proximeters and motors of agents with occlusion\n", + "\n", + "Logic for computing sensors and motors: \n", + "\n", + "- We get the raw proxs\n", + "- We get the ent types of the two detected entities (left and right)\n", + "- For each behavior, we updated the proxs according to the detected and the sensed entities (e.g sensed entities = [0, 1, 0 , 0] : only sense ent of type 1)\n", + "- We then compute the motor values for each behavior and do a mean of them " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create functions to update the two proximeter of an agent for a specific behavior \n", + "\n", + "- We already have the two closest proximeters in this case\n", + "- We want to compute the value of motors associated to a behavior for these proxs\n", + "- We can sense different type of entities \n", + "- The two proximeters are each associated to a specific entity type\n", + "- So if the specific entity type is detected, the proximeter value is kept \n", + "- Else it is set to 0 so it won't have effect on the motor values \n", + "- To do so we use a mask (mask of 1's, if an entity is detected we set it to 0 with a multiplication)\n", + "- So if the mask is already set to 0 (i.e the ent is detected), the masked value will still be 0 even if you multiply it by 1\n", + "- Then we update the proximeter values with a jnp.where" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "def update_mask(mask, left_n_right_types, ent_type):\n", + " \"\"\"Update a mask of \n", + "\n", + " :param mask: mask that will be applied on sensors of agents\n", + " :param left_n_right_types: types of left adn right sensed entities\n", + " :param ent_type: entity subtype (e.g 1 for predators)\n", + " :return: mask\n", + " \"\"\"\n", + " cur = jnp.where(left_n_right_types == ent_type, 0, 1)\n", + " mask *= cur\n", + " return mask\n", + "\n", + "def keep_mask(mask, left_n_right_types, ent_type):\n", + " \"\"\"Return the mask unchanged\n", + "\n", + " :param mask: mask\n", + " :param left_n_right_types: left_n_right_types\n", + " :param ent_type: ent_type\n", + " :return: mask\n", + " \"\"\"\n", + " return mask\n", + "\n", + "def mask_proxs_occlusion(proxs, left_n_right_types, ent_sensed_arr):\n", + " \"\"\"Mask the proximeters of agents with occlusion\n", + "\n", + " :param proxs: proxiemters of agents without occlusion (shape = (2,))\n", + " :param e_sensed_types: types of both entities sensed at left and right (shape=(2,))\n", + " :param ent_sensed_arr: mask of sensed subtypes by the agent (e.g jnp.array([0, 1, 0, 1]) if sense only entities of subtype 1 and 4)\n", + " :return: updated proximeters according to sensed_subtypes\n", + " \"\"\"\n", + " mask = jnp.array([1, 1])\n", + " # Iterate on the array of sensed entities mask\n", + " for ent_type, sensed in enumerate(ent_sensed_arr):\n", + " # If an entity is sensed, update the mask, else keep it as it is\n", + " mask = jax.lax.cond(sensed, update_mask, keep_mask, mask, left_n_right_types, ent_type)\n", + " # Update the mask with 0s where the mask is, else keep the prox value\n", + " proxs = jnp.where(mask, 0, proxs)\n", + " return proxs\n", + "\n", + "# Example :\n", + "# ent_sensed_arr = jnp.array([0, 1, 0, 0, 1])\n", + "# proxs = jnp.array([0.8, 0.2])\n", + "# e_sensed_types = jnp.array([4, 4]) # Modify these values to check it works\n", + "# print(mask_proxs_occlusion(proxs, e_sensed_types, ent_sensed_arr))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create a function to compute the motor values for a specific behavior \n", + "\n", + "- Convert the idx of the detected entitites (associated to the values of the two proximeters) into their types\n", + "- Mask their sensors with the function presented above \n", + "- Compute the motors with the updated sensors" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "def compute_behavior_motors(state, params, sensed_mask, behavior, motor, agent_proxs, sensed_ent_idx):\n", + " \"\"\"_summary_\n", + "\n", + " :param state: state\n", + " :param params: behavior params params\n", + " :param sensed_mask: sensed_mask for this behavior\n", + " :param behavior: behavior\n", + " :param motor: motor values\n", + " :param agent_proxs: agent proximeters (unmasked)\n", + " :param sensed_ent_idx: idx of left and right entities sensed \n", + " :return: right motor values for this behavior \n", + " \"\"\"\n", + " left_n_right_types = state.entities.ent_subtype[sensed_ent_idx]\n", + " behavior_proxs = mask_proxs_occlusion(agent_proxs, left_n_right_types, sensed_mask)\n", + " motors = compute_motor(behavior_proxs, params, behaviors=behavior, motors=motor)\n", + " return motors\n", + "\n", + "# See for the vectorizing idx because already in a vmaped function here\n", + "compute_all_behavior_motors = vmap(compute_behavior_motors, in_axes=(None, 0, 0, 0, None, None, None))" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "def linear_behavior(proxs, params):\n", + " \"\"\"Compute the activation of motors with a linear combination of proximeters and parameters\n", + "\n", + " :param proxs: proximeter values of an agent\n", + " :param params: parameters of an agent (mapping proxs to motor values)\n", + " :return: motor values\n", + " \"\"\"\n", + " return params.dot(jnp.hstack((proxs, 1.)))\n", + "\n", + "def compute_motor(proxs, params, behaviors, motors):\n", + " \"\"\"Compute new motor values. If behavior is manual, keep same motor values. Else, compute new values with proximeters and params.\n", + "\n", + " :param proxs: proximeters of all agents\n", + " :param params: parameters mapping proximeters to new motor values\n", + " :param behaviors: array of behaviors\n", + " :param motors: current motor values\n", + " :return: new motor values\n", + " \"\"\"\n", + " manual = jnp.where(behaviors == Behaviors.MANUAL.value, 1, 0)\n", + " manual_mask = manual\n", + " linear_motor_values = linear_behavior(proxs, params)\n", + " motor_values = linear_motor_values * (1 - manual_mask) + motors * manual_mask\n", + " return motor_values" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Create a function to compute the motor values each agent" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "def compute_occlusion_proxs_motors(state, agent_idx, params, sensed, behaviors, motor, raw_proxs, ag_idx_dense_senders, ag_idx_dense_receivers):\n", + " \"\"\"_summary_\n", + "\n", + " :param state: state\n", + " :param agent_idx: agent idx in entities\n", + " :param params: params arrays for all agent's behaviors\n", + " :param sensed: sensed mask arrays for all agent's behaviors\n", + " :param behaviors: agent behaviors array\n", + " :param motor: agent motors\n", + " :param raw_proxs: raw_proximeters for all agents (shape=(n_agents * (n_entities - 1), 2))\n", + " :param ag_idx_dense_senders: ag_idx_dense_senders to get the idx of raw proxs (shape=(2, n_agents * (n_entities - 1))\n", + " :param ag_idx_dense_receivers: ag_idx_dense_receivers (shape=(n_agents, n_entities - 1))\n", + " :return: _description_\n", + " \"\"\"\n", + " behavior = jnp.expand_dims(behaviors, axis=1) \n", + " # Compute the neighbors idx of the agent and get its raw proximeters (of shape (n_entities -1 , 2))\n", + " ent_ag_neighs_idx = ag_idx_dense_senders[agent_idx]\n", + " agent_raw_proxs = raw_proxs[ent_ag_neighs_idx]\n", + "\n", + " # Get the max and arg max of these proximeters on axis 0, gives results of shape (2,)\n", + " agent_proxs = jnp.max(agent_raw_proxs, axis=0)\n", + " argmax = jnp.argmax(agent_raw_proxs, axis=0)\n", + " # Get the real entity idx of the left and right sensed entities from dense neighborhoods\n", + " sensed_ent_idx = ag_idx_dense_receivers[agent_idx][argmax]\n", + " \n", + " # Compute the motor values for all behaviors and do a mean on it\n", + " motor_values = compute_all_behavior_motors(state, params, sensed, behavior, motor, agent_proxs, sensed_ent_idx)\n", + " motors = jnp.mean(motor_values, axis=0)\n", + "\n", + " return agent_proxs, motors\n", + "\n", + "compute_all_agents_proxs_motors_occl = vmap(compute_occlusion_proxs_motors, in_axes=(None, 0, 0, 0, 0, 0, None, None, None))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2 : Add functions to compute the proximeters and motors of agents without occlusion" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Add Mask sensors and don't change functions\n", + "\n", + "- mask_sensors: mask sensors according to sensed entity type for an agent\n", + "- don't change: return agent raw_proxs (surely return either the masked or the same prox array according to a sensed e type)\n", + "\n", + "Then for each agent, we iterate on all of his behaviors. For each behavior, we iterate on each possible sensed entity type. If the entity is sensed, we keep the raw proximeters of the agent as they are currently. If it is not, we mask the proximeters of the specific (non sensed) entity type." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "def mask_sensors(state, agent_raw_proxs, ent_type_id, ent_neighbors_idx):\n", + " \"\"\"Mask the raw proximeters of agents for a specific entity type \n", + "\n", + " :param state: state\n", + " :param agent_raw_proxs: raw_proximeters of agent (shape=(n_entities - 1), 2)\n", + " :param ent_type_id: entity subtype id (e.g 0 for PREYS)\n", + " :param ent_neighbors_idx: idx of agent neighbors in entities arrays\n", + " :return: updated agent raw proximeters\n", + " \"\"\"\n", + " mask = jnp.where(state.entities.ent_subtype[ent_neighbors_idx] == ent_type_id, 0, 1)\n", + " mask = jnp.expand_dims(mask, 1)\n", + " mask = jnp.broadcast_to(mask, agent_raw_proxs.shape)\n", + " return agent_raw_proxs * mask\n", + "\n", + "def dont_change(state, agent_raw_proxs, ent_type_id, ent_neighbors_idx):\n", + " \"\"\"Leave the agent raw_proximeters unchanged\n", + "\n", + " :param state: state\n", + " :param agent_raw_proxs: agent_raw_proxs\n", + " :param ent_type_id: ent_type_id\n", + " :param ent_neighbors_idx: ent_neighbors_idx\n", + " :return: agent_raw_proxs\n", + " \"\"\"\n", + " return agent_raw_proxs" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Add compute_behavior_prox, compute_behavior_proxs_motors, compute_agent_proxs_motors\n", + "\n", + "- compute_behavior_prox: compute the proxs for one behavior (enumerate through all the sensed entities on this particular behavior)\n", + "- compute_behavior_proxs_motors: use fn above to compute the proxs and compute the motor values according to the behavior\n", + "- -vmap compute_all_behavior_proxs_motors: computes this for all the behaviors of an agent\n", + "- compute_agent_proxs_motors: compute the proximeters and motor values of an agent for all its behaviors. Just return mean motor value\n", + "- -vmap compute_all_agents_proxs_motors: computes this for all agents (vmap over params, sensed and agent_raw_proxs) " + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "def compute_behavior_prox(state, agent_raw_proxs, ent_neighbors_idx, sensed_entities):\n", + " \"\"\"Compute the proximeters for a specific behavior\n", + "\n", + " :param state: state\n", + " :param agent_raw_proxs: agent raw proximeters\n", + " :param ent_neighbors_idx: idx of agent neighbors\n", + " :param sensed_entities: array of sensed entities\n", + " :return: updated proximeters\n", + " \"\"\"\n", + " # iterate over all the types in sensed_entities and return if they are sensed or not\n", + " for ent_type_id, sensed in enumerate(sensed_entities):\n", + " # change the proxs if you don't perceive the entity, else leave them unchanged\n", + " agent_raw_proxs = lax.cond(sensed, dont_change, mask_sensors, state, agent_raw_proxs, ent_type_id, ent_neighbors_idx)\n", + " # Compute the final proxs with a max on the updated raw_proxs\n", + " proxs = jnp.max(agent_raw_proxs, axis=0)\n", + " return proxs\n", + "\n", + "def compute_behavior_proxs_motors(state, params, sensed, behavior, motor, agent_raw_proxs, ent_neighbors_idx):\n", + " \"\"\"Return the proximeters and the motors for a specific behavior\n", + "\n", + " :param state: state\n", + " :param params: params of the behavior\n", + " :param sensed: sensed mask of the behavior\n", + " :param behavior: behavior\n", + " :param motor: motor values\n", + " :param agent_raw_proxs: agent_raw_proxs\n", + " :param ent_neighbors_idx: ent_neighbors_idx\n", + " :return: behavior proximeters, behavior motors\n", + " \"\"\"\n", + " behavior_prox = compute_behavior_prox(state, agent_raw_proxs, ent_neighbors_idx, sensed)\n", + " behavior_motors = compute_motor(behavior_prox, params, behavior, motor)\n", + " return behavior_prox, behavior_motors\n", + "\n", + "# vmap on params, sensed and behavior (parallelize on all agents behaviors at once, but not motorrs because are the same)\n", + "compute_all_behavior_proxs_motors = vmap(compute_behavior_proxs_motors, in_axes=(None, 0, 0, 0, None, None, None))\n", + "\n", + "def compute_agent_proxs_motors(state, agent_idx, params, sensed, behavior, motor, raw_proxs, ag_idx_dense_senders, ag_idx_dense_receivers):\n", + " \"\"\"Compute the agent proximeters and motors for all behaviors\n", + "\n", + " :param state: state\n", + " :param agent_idx: idx of the agent in entities\n", + " :param params: array of params for all behaviors\n", + " :param sensed: array of sensed mask for all behaviors\n", + " :param behavior: array of behaviors\n", + " :param motor: motor values\n", + " :param raw_proxs: raw_proximeters of all agents\n", + " :param ag_idx_dense_senders: ag_idx_dense_senders to get the idx of raw proxs (shape=(2, n_agents * (n_entities - 1))\n", + " :param ag_idx_dense_receivers: ag_idx_dense_receivers (shape=(n_agents, n_entities - 1))\n", + " :return: array of agent_proximeters, mean of behavior motors\n", + " \"\"\"\n", + " behavior = jnp.expand_dims(behavior, axis=1)\n", + " ent_ag_idx = ag_idx_dense_senders[agent_idx]\n", + " ent_neighbors_idx = ag_idx_dense_receivers[agent_idx]\n", + " agent_raw_proxs = raw_proxs[ent_ag_idx]\n", + "\n", + " # vmap on params, sensed, behaviors and motorss (vmap on all agents)\n", + " agent_proxs, agent_motors = compute_all_behavior_proxs_motors(state, params, sensed, behavior, motor, agent_raw_proxs, ent_neighbors_idx)\n", + " mean_agent_motors = jnp.mean(agent_motors, axis=0)\n", + "\n", + " return agent_proxs, mean_agent_motors\n", + "\n", + "compute_all_agents_proxs_motors = vmap(compute_agent_proxs_motors, in_axes=(None, 0, 0, 0, 0, 0, None, None, None))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Add classical braitenberg force fn" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Create the main environment class" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "@struct.dataclass\n", + "class Neighbors:\n", + " neighbors: jnp.array\n", + " agents_neighs_idx: jnp.array\n", + " agents_idx_dense: jnp.array\n", + "\n", + "\n", + "#--- 4 Define the environment class with its different functions (step ...) ---#\n", + "class SelectiveSensorsEnv(BaseEnv):\n", + " def __init__(self, state, occlusion=True, seed=42):\n", + " \"\"\"Init the selective sensors braitenberg env \n", + "\n", + " :param state: simulation state already complete\n", + " :param occlusion: wether to use sensors with occlusion or not, defaults to True\n", + " :param seed: random seed, defaults to 42\n", + " \"\"\"\n", + " self.seed = seed\n", + " self.occlusion = occlusion\n", + " self.compute_all_agents_proxs_motors = self.choose_agent_prox_motor_function()\n", + " self.init_key = random.PRNGKey(seed)\n", + " self.displacement, self.shift = space.periodic(state.box_size)\n", + " self.init_fn, self.apply_physics = dynamics_fn(self.displacement, self.shift, braintenberg_force_fn)\n", + " self.neighbor_fn = partition.neighbor_list(\n", + " self.displacement, \n", + " state.box_size,\n", + " r_cutoff=state.neighbor_radius,\n", + " dr_threshold=10.,\n", + " capacity_multiplier=1.5,\n", + " format=partition.Sparse\n", + " )\n", + " self.neighbors_storage = self.allocate_neighbors(state)\n", + "\n", + " def distance(self, point1, point2):\n", + " \"\"\"Returns the distance between two points\n", + "\n", + " :param point1: point1 coordinates\n", + " :param point2: point1 coordinates\n", + " :return: distance between two points\n", + " \"\"\"\n", + " return distance(self.displacement, point1, point2)\n", + " \n", + " # At the moment doesn't work because the _step function isn't recompiled \n", + " def choose_agent_prox_motor_function(self):\n", + " \"\"\"Returns the function to compute the proximeters and the motors with or without occlusion\n", + "\n", + " :return: compute_all_agents_proxs_motors function\n", + " \"\"\"\n", + " if self.occlusion:\n", + " prox_motor_function = compute_all_agents_proxs_motors_occl\n", + " else:\n", + " prox_motor_function = compute_all_agents_proxs_motors\n", + " return prox_motor_function\n", + " \n", + " @partial(jit, static_argnums=(0,))\n", + " def _step(self, state: State, neighbors_storage: Neighbors) -> Tuple[State, jnp.array]:\n", + " \"\"\"Do 1 jitted step in the environment and return the updated state\n", + "\n", + " :param state: current state\n", + " :param neighbors_storage: class storing all neighbors information\n", + " :return: new sttae\n", + " \"\"\"\n", + "\n", + " # Retrieve different neighbors format\n", + " neighbors = neighbors_storage.neighbors\n", + " agents_neighs_idx = neighbors_storage.agents_neighs_idx\n", + " ag_idx_dense = neighbors_storage.agents_idx_dense\n", + " # Differences : compute raw proxs for all agents first \n", + " dist, relative_theta, proximity_dist_map, proximity_dist_theta = get_relative_displacement(state, agents_neighs_idx, displacement_fn=self.displacement)\n", + " senders, receivers = agents_neighs_idx\n", + "\n", + " dist_max = state.agents.proxs_dist_max[senders]\n", + " cos_min = state.agents.proxs_cos_min[senders]\n", + " target_exist_mask = state.entities.exists[agents_neighs_idx[1, :]]\n", + " raw_proxs = sensor_fn(dist, relative_theta, dist_max, cos_min, target_exist_mask)\n", + "\n", + " # Could even just pass ag_idx_dense in the fn and do this inside\n", + " ag_idx_dense_senders, ag_idx_dense_receivers = ag_idx_dense\n", + "\n", + " agent_proxs, mean_agent_motors = self.compute_all_agents_proxs_motors(\n", + " state,\n", + " state.agents.ent_idx,\n", + " state.agents.params,\n", + " state.agents.sensed,\n", + " state.agents.behavior,\n", + " state.agents.motor,\n", + " raw_proxs,\n", + " ag_idx_dense_senders,\n", + " ag_idx_dense_receivers,\n", + " )\n", + "\n", + " agents = state.agents.replace(\n", + " prox=agent_proxs, \n", + " proximity_map_dist=proximity_dist_map, \n", + " proximity_map_theta=proximity_dist_theta,\n", + " motor=mean_agent_motors\n", + " )\n", + "\n", + " # Last block unchanged\n", + " state = state.replace(agents=agents)\n", + " entities = self.apply_physics(state, neighbors)\n", + " state = state.replace(time=state.time+1, entities=entities)\n", + " neighbors = neighbors.update(state.entities.position.center)\n", + "\n", + " return state, neighbors\n", + " \n", + " def step(self, state: State) -> State:\n", + " \"\"\"Do 1 step in the environment and return the updated state. This function also handles the neighbors mechanism and hence isn't jitted\n", + "\n", + " :param state: current state\n", + " :return: next state\n", + " \"\"\"\n", + " # Because momentum is initialized to None, need to initialize it with init_fn from jax_md\n", + " if state.entities.momentum is None:\n", + " state = self.init_fn(state, self.init_key)\n", + " \n", + " # Compute next state\n", + " current_state = state\n", + " state, neighbors = self._step(current_state, self.neighbors_storage)\n", + "\n", + " # Check if neighbors buffer overflowed\n", + " if neighbors.did_buffer_overflow:\n", + " # reallocate neighbors and run the simulation from current_state\n", + " lg.warning(f'NEIGHBORS BUFFER OVERFLOW at step {state.time}: rebuilding neighbors')\n", + " self.neighbors_storage = self.allocate_neighbors(state)\n", + " assert not neighbors.did_buffer_overflow\n", + "\n", + " return state\n", + "\n", + " def allocate_neighbors(self, state, position=None):\n", + " \"\"\"Allocate the neighbors according to the state\n", + "\n", + " :param state: state\n", + " :param position: position of entities in the state, defaults to None\n", + " :return: Neighbors object with neighbors (sparse representation), idx of agent's neighbors, neighbors (dense representation) \n", + " \"\"\"\n", + " # get the sparse representation of neighbors (shape=(n_neighbors_pairs, 2))\n", + " position = state.entities.position.center if position is None else position\n", + " neighbors = self.neighbor_fn.allocate(position)\n", + "\n", + " # Also update the neighbor idx of agents\n", + " ag_idx = state.entities.entity_type[neighbors.idx[0]] == EntityType.AGENT.value\n", + " agents_neighs_idx = neighbors.idx[:, ag_idx]\n", + "\n", + " # Give the idx of the agents in sparse representation, under a dense representation (used to get the raw proxs in compute motors function)\n", + " agents_idx_dense_senders = jnp.array([jnp.argwhere(jnp.equal(agents_neighs_idx[0, :], idx)).flatten() for idx in jnp.arange(state.max_agents)]) \n", + " # Note: jnp.argwhere(jnp.equal(self.agents_neighs_idx[0, :], idx)).flatten() ~ jnp.where(agents_idx[0, :] == idx)\n", + " \n", + " # Give the idx of the agent neighbors in dense representation\n", + " agents_idx_dense_receivers = agents_neighs_idx[1, :][agents_idx_dense_senders]\n", + " agents_idx_dense = agents_idx_dense_senders, agents_idx_dense_receivers\n", + "\n", + " neighbor_storage = Neighbors(neighbors=neighbors, agents_neighs_idx=agents_neighs_idx, agents_idx_dense=agents_idx_dense)\n", + " return neighbor_storage\n", + " \n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Create the state\n", + "\n", + "First define helper functions to create agents selctive sensing behaviors" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "# Helper function to transform a color string into rgb with matplotlib colors\n", + "def _string_to_rgb(color_str):\n", + " return jnp.array(list(mcolors.to_rgb(color_str)))\n", + "\n", + "# Helper functions to define behaviors of agents in selecting sensing case\n", + "def define_behavior_map(behavior, sensed_mask):\n", + " params = behavior_to_params(behavior)\n", + " sensed_mask = jnp.array([sensed_mask])\n", + "\n", + " behavior_map = {\n", + " 'behavior': behavior,\n", + " 'params': params,\n", + " 'sensed_mask': sensed_mask\n", + " }\n", + " return behavior_map\n", + "\n", + "def stack_behaviors(behaviors_dict_list):\n", + " # init variables\n", + " n_behaviors = len(behaviors_dict_list)\n", + " sensed_length = behaviors_dict_list[0]['sensed_mask'].shape[1]\n", + "\n", + " params = np.zeros((n_behaviors, 2, 3)) # (2, 3) = params.shape\n", + " sensed_mask = np.zeros((n_behaviors, sensed_length))\n", + " behaviors = np.zeros((n_behaviors,))\n", + "\n", + " # iterate in the list of behaviors and update params and mask\n", + " for i in range(n_behaviors):\n", + " assert behaviors_dict_list[i]['sensed_mask'].shape[1] == sensed_length\n", + " params[i] = behaviors_dict_list[i]['params']\n", + " sensed_mask[i] = behaviors_dict_list[i]['sensed_mask']\n", + " behaviors[i] = behaviors_dict_list[i]['behavior']\n", + "\n", + " stacked_behavior_map = {\n", + " 'behaviors': behaviors,\n", + " 'params': params,\n", + " 'sensed_mask': sensed_mask\n", + " }\n", + "\n", + " return stacked_behavior_map\n", + "\n", + "def get_agents_params_and_sensed_arr(agents_stacked_behaviors_list):\n", + " n_agents = len(agents_stacked_behaviors_list)\n", + " params_shape = agents_stacked_behaviors_list[0]['params'].shape\n", + " sensed_shape = agents_stacked_behaviors_list[0]['sensed_mask'].shape\n", + " behaviors_shape = agents_stacked_behaviors_list[0]['behaviors'].shape\n", + " # Init arrays w right shapes\n", + " params = np.zeros((n_agents, *params_shape))\n", + " sensed = np.zeros((n_agents, *sensed_shape))\n", + " behaviors = np.zeros((n_agents, *behaviors_shape))\n", + "\n", + " for i in range(n_agents):\n", + " assert agents_stacked_behaviors_list[i]['params'].shape == params_shape\n", + " assert agents_stacked_behaviors_list[i]['sensed_mask'].shape == sensed_shape\n", + " assert agents_stacked_behaviors_list[i]['behaviors'].shape == behaviors_shape\n", + " params[i] = agents_stacked_behaviors_list[i]['params']\n", + " sensed[i] = agents_stacked_behaviors_list[i]['sensed_mask']\n", + " behaviors[i] = agents_stacked_behaviors_list[i]['behaviors']\n", + "\n", + " params = jnp.array(params)\n", + " sensed = jnp.array(sensed)\n", + " behaviors = jnp.array(behaviors)\n", + "\n", + " return params, sensed, behaviors" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Define parameters" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "seed = 0\n", + "n_dims = 2\n", + "box_size = 100\n", + "diameter = 5.0\n", + "friction = 0.1\n", + "mass_center = 1.0\n", + "mass_orientation = 0.125\n", + "neighbor_radius = 100.0\n", + "collision_alpha = 0.5\n", + "collision_eps = 0.1\n", + "dt = 0.1\n", + "wheel_diameter = 2.0\n", + "speed_mul = 1.0\n", + "max_speed = 10.0\n", + "theta_mul = 1.0\n", + "prox_dist_max = 40.0\n", + "prox_cos_min = 0.0\n", + "existing_agents = None\n", + "existing_objects = None\n", + "\n", + "entities_sbutypes = ['PREYS', 'PREDS', 'RESSOURCES', 'POISON']\n", + "n_preys, preys_color = 5, 'blue'\n", + "n_preds, preds_color = 5, 'red'\n", + "n_ressources, ressources_color = 5, 'green'\n", + "n_poison, poison_color = 5, 'purple'\n", + "\n", + "preys_data = {\n", + " 'type': 'AGENT',\n", + " 'num': n_preys,\n", + " 'color': 'blue',\n", + " 'selective_behaviors': {\n", + " 'love': {'beh': 'LOVE', 'sensed': ['PREYS', 'RESSOURCES']},\n", + " 'fear': {'beh': 'FEAR', 'sensed': ['PREDS', 'POISON']}\n", + " }}\n", + "\n", + "preds_data = {\n", + " 'type': 'AGENT',\n", + " 'num': 5,\n", + " 'color': 'red',\n", + " 'selective_behaviors': {\n", + " 'aggr': {'beh': 'AGGRESSION','sensed': ['PREYS']},\n", + " 'fear': {'beh': 'FEAR','sensed': ['POISON']\n", + " }\n", + " }}\n", + "\n", + "ressources_data = {\n", + " 'type': 'OBJECT',\n", + " 'num': 5,\n", + " 'color': 'green'}\n", + "\n", + "poison_data = {\n", + " 'type': 'OBJECT',\n", + " 'num': 5,\n", + " 'color': 'purple'}\n", + "\n", + "entities_data = {\n", + " 'EntitySubTypes': entities_sbutypes,\n", + " 'Entities': {\n", + " 'PREYS': preys_data,\n", + " 'PREDS': preds_data,\n", + " 'RESSOURCES': ressources_data,\n", + " 'POISON': poison_data\n", + " }}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Entities\n", + "\n", + "Compared to simple Braitenberg env, just need to add a field ent_subtypes." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "def init_entities(\n", + " max_agents,\n", + " max_objects,\n", + " ent_sub_types,\n", + " n_dims=n_dims,\n", + " box_size=box_size,\n", + " existing_agents=None,\n", + " existing_objects=None,\n", + " mass_center=mass_center,\n", + " mass_orientation=mass_orientation,\n", + " diameter=diameter,\n", + " friction=friction,\n", + " key_agents_pos=random.PRNGKey(seed),\n", + " key_objects_pos=random.PRNGKey(seed+1),\n", + " key_orientations=random.PRNGKey(seed+2)\n", + "):\n", + " \"\"\"Init the sub entities state\"\"\"\n", + " existing_agents = max_agents if not existing_agents else existing_agents\n", + " existing_objects = max_objects if not existing_objects else existing_objects\n", + "\n", + " n_entities = max_agents + max_objects # we store the entities data in jax arrays of length max_agents + max_objects \n", + " # Assign random positions to each entity in the environment\n", + " agents_positions = random.uniform(key_agents_pos, (max_agents, n_dims)) * box_size\n", + " objects_positions = random.uniform(key_objects_pos, (max_objects, n_dims)) * box_size\n", + " positions = jnp.concatenate((agents_positions, objects_positions))\n", + " # Assign random orientations between 0 and 2*pi to each entity\n", + " orientations = random.uniform(key_orientations, (n_entities,)) * 2 * jnp.pi\n", + " # Assign types to the entities\n", + " agents_entities = jnp.full(max_agents, EntityType.AGENT.value)\n", + " object_entities = jnp.full(max_objects, EntityType.OBJECT.value)\n", + " entity_types = jnp.concatenate((agents_entities, object_entities), dtype=int)\n", + " # Define arrays with existing entities\n", + " exists_agents = jnp.concatenate((jnp.ones((existing_agents)), jnp.zeros((max_agents - existing_agents))))\n", + " exists_objects = jnp.concatenate((jnp.ones((existing_objects)), jnp.zeros((max_objects - existing_objects))))\n", + " exists = jnp.concatenate((exists_agents, exists_objects), dtype=int)\n", + "\n", + " # Works because dictionaries are ordered in Python\n", + " ent_subtypes = np.zeros(n_entities)\n", + " cur_idx = 0\n", + " for subtype_id, n_subtype in ent_sub_types.values():\n", + " ent_subtypes[cur_idx:cur_idx+n_subtype] = subtype_id\n", + " cur_idx += n_subtype\n", + " ent_subtypes = jnp.array(ent_subtypes, dtype=int) \n", + "\n", + " return EntityState(\n", + " position=RigidBody(center=positions, orientation=orientations),\n", + " momentum=None,\n", + " force=RigidBody(center=jnp.zeros((n_entities, 2)), orientation=jnp.zeros(n_entities)),\n", + " mass=RigidBody(center=jnp.full((n_entities, 1), mass_center), orientation=jnp.full((n_entities), mass_orientation)),\n", + " entity_type=entity_types,\n", + " ent_subtype=ent_subtypes,\n", + " entity_idx = jnp.array(list(range(max_agents)) + list(range(max_objects))),\n", + " diameter=jnp.full((n_entities), diameter),\n", + " friction=jnp.full((n_entities), friction),\n", + " exists=exists\n", + " )\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Agents\n", + "\n", + "Now this section becomes pretty different. We need to have several behaviors for each agent. \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "def init_agents(\n", + " max_agents,\n", + " params,\n", + " sensed,\n", + " behaviors,\n", + " agents_color,\n", + " wheel_diameter=wheel_diameter,\n", + " speed_mul=speed_mul,\n", + " max_speed=max_speed,\n", + " theta_mul=theta_mul,\n", + " prox_dist_max=prox_dist_max,\n", + " prox_cos_min=prox_cos_min\n", + "):\n", + " \"\"\"Init the sub agents state\"\"\"\n", + " return AgentState(\n", + " # idx in the entities (ent_idx) state to map agents information in the different data structures\n", + " ent_idx=jnp.arange(max_agents, dtype=int), \n", + " prox=jnp.zeros((max_agents, 2)),\n", + " motor=jnp.zeros((max_agents, 2)),\n", + " behavior=behaviors,\n", + " params=params,\n", + " sensed=sensed,\n", + " wheel_diameter=jnp.full((max_agents), wheel_diameter),\n", + " speed_mul=jnp.full((max_agents), speed_mul),\n", + " max_speed=jnp.full((max_agents), max_speed),\n", + " theta_mul=jnp.full((max_agents), theta_mul),\n", + " proxs_dist_max=jnp.full((max_agents), prox_dist_max),\n", + " proxs_cos_min=jnp.full((max_agents), prox_cos_min),\n", + " proximity_map_dist=jnp.zeros((max_agents, 1)),\n", + " proximity_map_theta=jnp.zeros((max_agents, 1)),\n", + " color=agents_color\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "def init_objects(\n", + " max_agents,\n", + " max_objects,\n", + " objects_color\n", + "):\n", + " \"\"\"Init the sub objects state\"\"\"\n", + " start_idx, stop_idx = max_agents, max_agents + max_objects \n", + " objects_ent_idx = jnp.arange(start_idx, stop_idx, dtype=int)\n", + "\n", + " return ObjectState(\n", + " ent_idx=objects_ent_idx,\n", + " color=objects_color\n", + " )" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### State" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "def init_complete_state(\n", + " entities,\n", + " agents,\n", + " objects,\n", + " max_agents,\n", + " max_objects,\n", + " total_ent_sub_types,\n", + " box_size=box_size,\n", + " neighbor_radius=neighbor_radius,\n", + " collision_alpha=collision_alpha,\n", + " collision_eps=collision_eps,\n", + " dt=dt,\n", + "):\n", + " \"\"\"Init the complete state\"\"\"\n", + " return State(\n", + " time=0,\n", + " dt=dt,\n", + " box_size=box_size,\n", + " max_agents=max_agents,\n", + " max_objects=max_objects,\n", + " neighbor_radius=neighbor_radius,\n", + " collision_alpha=collision_alpha,\n", + " collision_eps=collision_eps,\n", + " entities=entities,\n", + " agents=agents,\n", + " objects=objects,\n", + " ent_sub_types=total_ent_sub_types\n", + " ) " + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "def init_state(\n", + " entities_data,\n", + " box_size=box_size,\n", + " dt=dt,\n", + " neighbor_radius=neighbor_radius,\n", + " collision_alpha=collision_alpha,\n", + " collision_eps=collision_eps,\n", + " n_dims=n_dims,\n", + " seed=seed,\n", + " diameter=diameter,\n", + " friction=friction,\n", + " mass_center=mass_center,\n", + " mass_orientation=mass_orientation,\n", + " existing_agents=None,\n", + " existing_objects=None,\n", + " wheel_diameter=wheel_diameter,\n", + " speed_mul=speed_mul,\n", + " max_speed=max_speed,\n", + " theta_mul=theta_mul,\n", + " prox_dist_max=prox_dist_max,\n", + " prox_cos_min=prox_cos_min,\n", + ") -> State:\n", + " key = random.PRNGKey(seed)\n", + " key, key_agents_pos, key_objects_pos, key_orientations = random.split(key, 4)\n", + " \n", + " # create an enum for entities subtypes\n", + " ent_sub_types = entities_data['EntitySubTypes']\n", + " ent_sub_types_enum = Enum('ent_sub_types_enum', {ent_sub_types[i]: i for i in range(len(ent_sub_types))}) \n", + " ent_data = entities_data['Entities']\n", + "\n", + " # create max agents and max objects\n", + " max_agents = 0\n", + " max_objects = 0 \n", + "\n", + " # create agent and objects dictionaries \n", + " agents_data = {}\n", + " objects_data = {}\n", + "\n", + " # iterate over the entities subtypes\n", + " for ent_sub_type in ent_sub_types:\n", + " # get their data in the ent_data\n", + " data = ent_data[ent_sub_type]\n", + " color_str = data['color']\n", + " color = _string_to_rgb(color_str)\n", + " n = data['num']\n", + "\n", + " # Check if the entity is an agent or an object\n", + " if data['type'] == 'AGENT':\n", + " max_agents += n\n", + " behavior_list = []\n", + " # create a behavior list for all behaviors of the agent\n", + " for beh_name, behavior_data in data['selective_behaviors'].items():\n", + " beh_name = behavior_data['beh']\n", + " behavior_id = Behaviors[beh_name].value\n", + " # Init an empty mask\n", + " sensed_mask = np.zeros((len(ent_sub_types, )))\n", + " for sensed_type in behavior_data['sensed']:\n", + " # Iteratively update it with specific sensed values\n", + " sensed_id = ent_sub_types_enum[sensed_type].value\n", + " sensed_mask[sensed_id] = 1\n", + " beh = define_behavior_map(behavior_id, sensed_mask)\n", + " behavior_list.append(beh)\n", + " # stack the elements of the behavior list and update the agents_data dictionary\n", + " stacked_behaviors = stack_behaviors(behavior_list)\n", + " agents_data[ent_sub_type] = {'n': n, 'color': color, 'stacked_behs': stacked_behaviors}\n", + "\n", + " # only updated object counters and color if entity is an object\n", + " elif data['type'] == 'OBJECT':\n", + " max_objects += n\n", + " objects_data[ent_sub_type] = {'n': n, 'color': color}\n", + "\n", + " # Create the params, sensed, behaviors and colors arrays \n", + "\n", + " # init empty lists\n", + " colors = []\n", + " agents_stacked_behaviors_list = []\n", + " total_ent_sub_types = {}\n", + " for agent_type, data in agents_data.items():\n", + " n = data['n']\n", + " stacked_behavior = data['stacked_behs']\n", + " n_stacked_behavior = list([stacked_behavior] * n)\n", + " tiled_color = list(np.tile(data['color'], (n, 1)))\n", + " # update the lists with behaviors and color elements\n", + " agents_stacked_behaviors_list = agents_stacked_behaviors_list + n_stacked_behavior\n", + " colors = colors + tiled_color\n", + " total_ent_sub_types[agent_type] = (ent_sub_types_enum[agent_type].value, n)\n", + "\n", + " # create the final jnp arrays\n", + " agents_colors = jnp.concatenate(jnp.array([colors]), axis=0)\n", + " params, sensed, behaviors = get_agents_params_and_sensed_arr(agents_stacked_behaviors_list)\n", + "\n", + " # do the same for objects colors\n", + " colors = []\n", + " for objecy_type, data in objects_data.items():\n", + " n = data['n']\n", + " tiled_color = list(np.tile(data['color'], (n, 1)))\n", + " colors = colors + tiled_color\n", + " total_ent_sub_types[objecy_type] = (ent_sub_types_enum[objecy_type].value, n)\n", + "\n", + " objects_colors = jnp.concatenate(jnp.array([colors]), axis=0)\n", + " # print(total_ent_sub_types)\n", + "\n", + " # Init sub states and total state\n", + " entities = init_entities(max_agents=max_agents, max_objects=max_objects, ent_sub_types=total_ent_sub_types)\n", + " agents = init_agents(max_agents=max_agents, behaviors=behaviors, params=params, sensed=sensed, agents_color=agents_colors)\n", + " objects = init_objects(max_agents=max_agents, max_objects=max_objects, objects_color=objects_colors)\n", + " state = init_complete_state(entities=entities, agents=agents, objects=objects, max_agents=max_agents, max_objects=max_objects, total_ent_sub_types=total_ent_sub_types)\n", + " return state\n", + "\n", + "state = init_state(entities_data=entities_data)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Recap of the state\n", + "\n", + "### Agents\n", + "\n", + "Preys:\n", + "- Love: other preys and ressources\n", + "- Fear: predators and poison\n", + "- Color: Blue\n", + "\n", + "Predators:\n", + "- Aggression: preys\n", + "- Fear: Poison\n", + "- Color: Red\n", + "\n", + "### Objects\n", + "\n", + "Ressources\n", + "- Color: green\n", + "\n", + "Poison\n", + "- Color: purple" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Test the simulation" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [], + "source": [ + "from vivarium.experimental.environments.braitenberg.render import render, render_history" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAikAAAIjCAYAAADGCIt4AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAABhHUlEQVR4nO3dd3gU5d7G8e/sbholGwgkIRB6F6QHKSpoFLAiiA0RUUFpitiPr/0oqMdyAAFFBQvYBcUCIs2DBAhdpCnSIaEmgUDa7rx/rKxGAqTsZifJ/fHaSzLl2d9OSObmmWeeMUzTNBERERGxGFugCxARERHJj0KKiIiIWJJCioiIiFiSQoqIiIhYkkKKiIiIWJJCioiIiFiSQoqIiIhYkkKKiIiIWJJCioiIiFiSQoqIiIhYkkKKiPjcL7/8wvXXX0+dOnUIDQ2lZs2aXHbZZYwfP967zQsvvMCsWbOK/B4bN27k6aefZseOHcUvWEQsydCze0TEl5YuXUr37t2pXbs2AwcOJCYmht27d7Ns2TK2bdvG77//DkClSpW4/vrrmTZtWpHe5/PPP6dfv34sXLiQbt26+e4DiIhlOAJdgIiULc8//zxOp5OkpCQiIiLyrDtw4EBgihKRUkmXe0TEp7Zt28Z55513WkABiIqKAsAwDDIyMnjvvfcwDAPDMLj99tsB2LlzJ8OGDaNJkyaEhYURGRlJv3798lzWmTZtGv369QOge/fu3jYWLVrk3eb777/nwgsvpGLFilSuXJkrr7ySX3/91V8fW0T8QD0pIuJTderUITExkQ0bNtCiRYt8t/nggw+46667iI+PZ8iQIQA0aNAAgKSkJJYuXcpNN91ErVq12LFjB5MmTaJbt25s3LiRChUqcNFFF3Hvvfcybtw4/vWvf9GsWTMA7/8/+OADBg4cSI8ePXjxxRc5ceIEkyZNomvXrqxZs4a6dev6/0CISLFpTIqI+NS8efPo1asXAPHx8Vx44YVceumldO/enaCgIO92ZxqTcvLkScLCwvIsW7ZsGZ06deL9999nwIABwJnHpBw/fpy4uDj69evHW2+95V2ekpJCkyZNuOGGG/IsFxHr0uUeEfGpyy67jMTERK655hrWrVvHSy+9RI8ePahZsyZff/31Off/e0DJycnh8OHDNGzYkIiICFavXn3O/efNm0dqaio333wzhw4d8r7sdjsdO3Zk4cKFxfp8IlJydLlHRHyuQ4cOfPnll2RnZ7Nu3TpmzpzJa6+9xvXXX8/atWtp3rz5Gfc9efIkY8aMYerUqezdu5e/d/ampaWd871/++03AC655JJ814eHhxfy04hIoCikiIjfBAcH06FDBzp06EDjxo0ZNGgQn332GU899dQZ9xk5ciRTp05l1KhRdOrUCafTiWEY3HTTTbjd7nO+56ltPvjgA2JiYk5b73Do155IaaGfVhEpEe3btwdg//79gOcOn/x8/vnnDBw4kFdeecW7LDMzk9TU1DzbnWn/UwNwo6KiSEhIKG7ZIhJAGpMiIj61cOFC8huP/9133wHQpEkTACpWrHha8ACw2+2n7T9+/HhcLleeZRUrVgQ4rY0ePXoQHh7OCy+8QE5OzmntHzx4sMCfRUQCSz0pIuJTI0eO5MSJE1x33XU0bdqU7Oxsli5dyieffELdunUZNGgQAO3atePHH3/k1VdfJTY2lnr16tGxY0euuuoqPvjgA5xOJ82bNycxMZEff/yRyMjIPO/TunVr7HY7L774ImlpaYSEhHDJJZcQFRXFpEmTGDBgAG3btuWmm26ievXq7Nq1i2+//ZYuXbowYcKEQBwaESksU0TEh77//nvzjjvuMJs2bWpWqlTJDA4ONhs2bGiOHDnSTElJ8W63efNm86KLLjLDwsJMwBw4cKBpmqZ59OhRc9CgQWa1atXMSpUqmT169DA3b95s1qlTx7vNKVOmTDHr169v2u12EzAXLlzoXbdw4UKzR48eptPpNENDQ80GDRqYt99+u7ly5coSOAoi4guaJ0VEREQsSWNSRERExJIUUkRERMSSFFJERETEkhRSRERExJIUUkRERMSSFFJERETEkjSZG55nfezbt4/KlSufcaptEREROZ1pmhw7dozY2FhsNh/3fQRykpbFixebV111lVmjRg0TMGfOnJlnvdvtNp944gkzJibGDA0NNS+99FJz69atebY5fPiwecstt5iVK1c2nU6neccdd5jHjh0rVB27d+82Ab300ksvvfTSq4iv3bt3FzcWnCagPSkZGRm0atWKO+64gz59+py2/qWXXmLcuHG899571KtXjyeeeIIePXqwceNGQkNDAejfvz/79+9n3rx55OTkMGjQIIYMGcKMGTMKXEflypUB2L17tx7jLiIiUgjp6enExcV5z6W+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2LVrF59++inz5s0jISEBgPp/e2pi1apVAYiKiiIiIgLwBJ/c3Fz69OlDnTp1AGjZsmWxPrs/qCelPIuLK9qdPX+Xm6sHYIhIwPiq9wMgPSu92G1s27aNnJwcunTp4l0WFBREfHw8mzZt8i7r1KmT989Vq1alSZMmedb/3bp165g2bRqVKlXyvnr06IHb7Wb79u2sXbsWu93OxRdfXOA6W7VqxaWXXkrLli3p168fU6ZM4ejRo0X4xP6lkFKe3XrrXxO0FZXD4XmCl4hIAFQKruSztiqHVPZZW750/Phx7r77btauXet9rVu3jt9++40GDRoQVoRecbvdzrx58/j+++9p3rw548ePp0mTJmzfvt0Pn6DoFFLKs759oUqVou/vcHie41Otmu9qEhEphKiKUVQIqlDsdhw2B7XCaxW7nQYNGhAcHMzPP//sXZaTk0NSUhLNmzf3Llu2bJn3z0ePHmXr1q00O8MM3m3btmXjxo00bNjwtFdwcDAtW7bE7XazePHifPcPDg4GwPWP6SYMw6BLly4888wzrFmzhuDgYGbOnFnkz+4PCinlWUgIDBtW9Es+ubkwfLhvaxIRKYQQRwi3t7odh63oQywdNgc3tbjJJ1PkV6xYkaFDh/LQQw8xZ84cNm7cyODBgzlx4gR33nmnd7tnn32W+fPns2HDBm6//XaqVatG7969823zkUceYenSpYwYMYK1a9fy22+/8dVXX3kHztatW5eBAwdyxx13MGvWLLZv386iRYv49NNPAahTpw6GYfDNN99w8OBBjh8/zvLly3nhhRdYuXIlu3bt4ssvv+TgwYNnDEqBopBS3j3+OLRr57mVuLCeegri431fk4hIIQztMNQ75X1R5LpzGd7Bd//gGjt2LH379mXAgAG0bduW33//nblz51Llbz3XY8eO5b777qNdu3YkJycze/Zsb4/HP51//vksXryYrVu3cuGFF9KmTRuefPJJYmNjvdtMmjSJ66+/nmHDhtG0aVMGDx7svZ24Zs2aPPPMMzz66KNER0czYsQIwsPD+emnn7jiiito3Lgx//d//8crr7ziHexrFYZptfuNAiA9PR2n00laWhrh4eXwYVOHDkGvXrB6dcHHqDzwALz8MmiyIRHxg8zMTLZv3069evUILcAdhAnvJ7B4x+JCzTgLYDfstK3RluV3LbfM5Glz586lV69eZGZmnjG4lLSzfT/8eQ5VT4p4xpQsXgz33QcVK3qCxz9/WE/NTFuvHkydCv/5jwKKiFjGR30/omZ4zUJd9nEYDqpVqMaXN35pmYCSkpLCV199RaNGjSwTUAJJIUU8KlSAV1+FlBR4803PZZwaNSAiwnOr8lVXwbx58Pvv8OdshSIiVlG9YnV+GvQTDao0wGac+9RmN+zUctZiyR1LfDJg1leuuOIKfvzxR954441Al2IJmsxN8qpYEQYP9rxEREqR2s7aLL9rOeOWj2PiyokkH0/GYXN4x6uc+nO1CtUY2n4o93W8j8gKkQGuOq9Vq1YFugRLUUgREZEywxnq5ImLn+CxCx/jm63fMHvLbA6fPIxpmlStUJVeDXtxXdPrCLIHBbpUKQCFFBERsayi3tvhsDno3bQ3vZv29m1B5VSg7rHRmBQREbEc+5/TImRnZwe4EgE4ceIE4JnivySpJ0VERCzH4XBQoUIFDh48SFBQELbiPmdMisQ0TU6cOMGBAweIiIjwhseSopAiIiKWYxgGNWrUYPv27ezcuTPQ5ZR7ERERxMTElPj7KqSIiIglBQcH06hRI13yCbCgoKAS70E5RSFFRKQ8S08HC8+0bbPZCjTjrJRNusgnIlKebdoU6ApEzkghRUSkPPv1V9Aj3MSiFFJERMoztxs2bw50FSL5UkgRESmv1q2DL7+Eyy7zPDy0eXPo2RM++gg0WFUsQANnRUTKm++/h2eegeXLwW4Hl+uvdVu2wNy5ULUqDB8O//oXaOCqBIh6UkREypPXXoMrr4SkJM/Xfw8o4Ln8A3DkCDz/PFxyCRw9WrI1ivxJIUVEpLx4800YPdozUPZUGDkbtxtWrPCEmsxM/9cn8g8KKSIi5cFvv8GwYYXfz+XyXBZ69lnf1yRyDgopIiLlwaRJYBhF29fthokT1ZsiJU4hRUSkrDtxAt5++/TxJ4WRlgaffea7mkQKQCFFRKSs++YbOHaseG3YbPDuu76pR6SAFFJERMq63bs9txoXh9sNehqxlDCFFBGRsu7EiaKPR/k7jUmREqaQIiJS1jmdBbvluCDtiJQghRQRkbKuTZvihxSHA9q18009IgWkkCIiUtZ17QqNGxfvkk9ubtHmWREpBoUUEZGyzjDg3nuLt/9550GnTr6rSaQAFFJERMqDAQMgJqZod/mYJjz1lG8G34oUgkKKiEh5EB4OP/wAYWGFDypPPQX9+vmnLpGzUEgRESkvWrSApUuhenVPr8jZekYcDs//X3rJE1JEAkAhRUSkPGnZEjZtgtdeg3r1PMvsdggK8gQTw4DQULjjDli7Fh56SJd5JGAM0zTNQBcRaOnp6TidTtLS0ggPDw90OSIiJcM0YcECWL3a82yesDCIjYXrroOIiEBXJ6WEP8+hDp+2JiIipYdhwKWXel4iFqTLPSIiImJJCikiIiJiSQopIiIiYkkKKSIiImJJCikiIiJiSQopIiIiYkkKKSIiImJJCikiIiJiSQopIiIiYkkKKSIiImJJlg4pLpeLJ554gnr16hEWFkaDBg147rnn+PvjhkzT5Mknn6RGjRqEhYWRkJDAb7/9FsCqRYTNm2HUKGjYEKpWhchIaNwYHn0Utm8PdHUiUkpYOqS8+OKLTJo0iQkTJrBp0yZefPFFXnrpJcaPH+/d5qWXXmLcuHFMnjyZ5cuXU7FiRXr06EFmZmYAKxcpp1atgm7doFkzeOMN2LYNjh6FI0fgt9/gP/+BBg3giis8T+IVETkLSz8F+aqrriI6Opp33nnHu6xv376EhYXx4YcfYpomsbGxPPDAAzz44IMApKWlER0dzbRp07jpppvybTcrK4usrCzv1+np6cTFxekpyCLF8e230Lcv5OaCy3X2be12qFDBs8+FF5ZMfSLiF/58CrKle1I6d+7M/Pnz2bp1KwDr1q1jyZIl9OrVC4Dt27eTnJxMQkKCdx+n00nHjh1JTEw8Y7tjxozB6XR6X3Fxcf79ICJl3f/+B717Q3b2uQMKeLbJyICePWH9er+XJyKlk6VDyqOPPspNN91E06ZNCQoKok2bNowaNYr+/fsDkJycDEB0dHSe/aKjo73r8vPYY4+Rlpbmfe3evdt/H0KkrMvJgX79wO2GwnTMut2QlQU33VS4/USk3HAEuoCz+fTTT5k+fTozZszgvPPOY+3atYwaNYrY2FgGDhxY5HZDQkIICQnxYaUi5djXX0NKStH2dbk8Y1OWLNFlHxE5jaV7Uh566CFvb0rLli0ZMGAA999/P2PGjAEgJiYGgJR//IJMSUnxrhMRPxs/3jPGpKgcDs8gWxGRf7B0T8qJEyew2fLmKLvdjtvtBqBevXrExMQwf/58WrduDXgG8CxfvpyhQ4eWdLki5c/+/bB4cfHayM2Fzz6DDh08l39q1oTmzaFpU6hc2Td1ikipZOmQcvXVV/P8889Tu3ZtzjvvPNasWcOrr77KHXfcAYBhGIwaNYp///vfNGrUiHr16vHEE08QGxtL7969A1u8SHmwf79v2nG7ISYGrroKnE7ftCkipZ6lQ8r48eN54oknGDZsGAcOHCA2Npa7776bJ5980rvNww8/TEZGBkOGDCE1NZWuXbsyZ84cQkNDA1i5SDnxt1v5i61jRwUUEcnD0vOklBR/3uMtUqZt3Ajnneebtg4ehGrVfNOWiJSYcjtPiohYXP36vun9qF3bM3W+iMjfKKSISNGFhsKQIcW7u8dmg5EjwTB8V5eIlAkKKSJSPHff7Rn4WlR2Owwa5Lt6RKTMUEgRkeJp0AAGDPD0iBSWYcB99+lSj4jkSyFFRIrvrbegS5fCBRXDgGuugbFj/VeXiJRqCikiUnwhITB3rid0gGcW2TM5tW7QIM8kbsUZzyIiZZpCioj4RlgYfPklLFwI1177V6+KzfbXnx0OzwMFly6Ft9+GoKDA1SsilmfpydxEpJQxDOjWzfPatw8WLIAjRzzLIyPh8ss1F4qIFJhCioj4R2ws3HproKsQkVJMl3tERETEkhRSRERExJIUUkRERMSSFFJERETEkhRSRERExJIUUkRERMSSFFJERETEkhRSRERExJIUUkRERMSSFFJERETEkhRSRERExJIUUkRERMSSFFJERETEkhRSRERExJIUUkRERMSSFFJERETEkhRSRERExJIUUkRERMSSFFJERETEkhRSRERExJIUUkRERMSSFFJERETEkhRSRERExJIUUkRERMSSFFJERETEkhRSRERExJIUUkRERMSSFFJERETEkhRSRERExJIUUkRERMSSFFJERETEkhRSRERExJIUUkRERMSSFFJERETEkhRSRERExJIUUkRERMSSFFJERETEkhRSRERExJIUUkRERMSSFFJERETEkhRSRERExJIUUkRERMSSFFJERETEkhRSRERExJIUUkRERMSSFFJERETEkhRSRERExJIUUkRERMSSFFJERETEkhRSRERExJIUUkRERMSSFFJERETEkhRSRERExJIUUkRERMSSFFJERETEkhRSRERExJIUUkRERMSSFFJERETEkhRSRERExJIUUkRERMSSFFJERETEkhRSRERExJIUUkRERMSSFFJERETEkhRS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EbEk9aSIiIiIJSmkiIiIiCUppIiIiIglKaSIiIiIJZX7kPLGG29Qt25dQkND6dixIytWrAh0SWXGmDFj6NChA5UrVyYqKorevXuzZcuWPNtkZmYyfPhwIiMjqVSpEn379iUlJSVAFZc9Y8eOxTAMRo0a5V2mY+57e/fu5dZbbyUyMpKwsDBatmzJypUrvetN0+TJJ5+kRo0ahIWFkZCQwG+//RbAiks3l8vFE088Qb169QgLC6NBgwY899xzeZ4do2NePD/99BNXX301sbGxGIbBrFmz8qwvyPE9cuQI/fv3Jzw8nIiICO68806OHz9euELMcuzjjz82g4ODzXfffdf89ddfzcGDB5sRERFmSkpKoEsrE3r06GFOnTrV3LBhg7l27VrziiuuMGvXrm0eP37cu80999xjxsXFmfPnzzdXrlxpXnDBBWbnzp0DWHXZsWLFCrNu3brm+eefb953333e5TrmvnXkyBGzTp065u23324uX77c/OOPP8y5c+eav//+u3ebsWPHmk6n05w1a5a5bt0685prrjHr1atnnjx5MoCVl17PP/+8GRkZaX7zzTfm9u3bzc8++8ysVKmS+d///te7jY558Xz33Xfm448/bn755ZcmYM6cOTPP+oIc3549e5qtWrUyly1bZv7vf/8zGzZsaN58882FqqNch5T4+Hhz+PDh3q9dLpcZGxtrjhkzJoBVlV0HDhwwAXPx4sWmaZpmamqqGRQUZH722WfebTZt2mQCZmJiYqDKLBOOHTtmNmrUyJw3b5558cUXe0OKjrnvPfLII2bXrl3PuN7tdpsxMTHmyy+/7F2WmppqhoSEmB999FFJlFjmXHnlleYdd9yRZ1mfPn3M/v37m6apY+5r/wwpBTm+GzduNAEzKSnJu833339vGoZh7t27t8DvXW4v92RnZ7Nq1SoSEhK8y2w2GwkJCSQmJgawsrIrLS0N+OuBjqtWrSInJyfP96Bp06bUrl1b34NiGj58OFdeeWWeYws65v7w9ddf0759e/r160dUVBRt2rRhypQp3vXbt28nOTk5zzF3Op107NhRx7yIOnfuzPz589m6dSsA69atY8mSJfTq1QvQMfe3ghzfxMREIiIiaN++vXebhIQEbDYby5cvL/B7ldsHDB46dAiXy0V0dHSe5dHR0WzevDlAVZVdbrebUaNG0aVLF1q0aAFA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gwdz//33M3ToUDZt2kRcXJw3oAA0b96ciIgINm3aBMDo0aO56667SEhIYOzYsWzbtq1Y9W/atIlWrVp5AwpAly5dcLvdbNmyxbvsvPPOw263e7+uUaMGBw4cKNZ7i0jRKKSIyDktXbqU1157jW+++Yb4+HjuvPNOTNM85379+/dn7dq1bN++nYyMDF599VVstoL92nn66af59ddfufLKK1mwYAHNmzdn5syZxf0o5/TPS0qGYeB2u/3+viJyOoUUETmrEydOcPvttzN06FC6d+/OO++8w4oVK5g8efI593U6nTRs2JCaNWvmCSfNmjVj9+7d7N6927ts48aNpKam0rx5c++yxo0bc//99/PDDz/Qp08fpk6dmu/7BAcH43K5zlpLs2bNWLduHRkZGd5lP//8MzabjSZNmpzzs4hIyVNIEZGzeuyxxzBNk7FjxwJQt25d/vOf//Dwww+zY8eOIrWZkJBAy5Yt6d+/P6tXr2bFihXcdtttXHzxxbRv356TJ08yYsQIFi1axM6dO/n5559JSkqiWbNm+bZXt25dtm/fztq1azl06BBZWVmnbdO/f39CQ0MZOHAgGzZsYOHChYwcOZIBAwZ4x6OIiLUopIjIGS1evJg33niDqVOnUqFCBe/yu+++m86dOxf4ss8/GYbBV199RZUqVbjoootISEigfv36fPLJJ4BnfpbDhw9z22230bhxY2644QZ69erFM888k297ffv2pWfPnnTv3p3q1avnOxdLhQoVmDt3LkeOHKFDhw5cf/31XHrppUyYMKHQ9YtIyTDMovyGEREREfEz9aSIiIiIJSmkiIiIiCUppIiIiIglKaSIiIiIJSmkiIiIiCUppIiIiIglKaSIiIiIJSmkiIiIiCUppIiIiIglKaSIiIiIJSmkiIiIiCX9P8I5Gwkfe9fAAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "render(state)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [], + "source": [ + "env = SelectiveSensorsEnv(state, occlusion=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [], + "source": [ + "n_steps = 5_000\n", + "hist = []\n", + "\n", + "for i in range(n_steps):\n", + " state = env.step(state)\n", + " hist.append(state)" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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SKxduxYajQb16tXDpk2bjAajzpo1Czdu3MD8+fORnp6OTp06oWvXrnBycsK+ffvw6aef4scff8SaNWvg6uqKOnXqYPbs2UYzkwBg+PDhUKlUWLhwIZKSktCqVSuEhYUZxndYU4sWLfDjjz/i1q1bcHV1Rbdu3fDRRx+hZs2aRse9+OKL+PXXX/H7778jKysLvr6+GDNmDN5//33DWi4F+vTpg82bN2P27NmYOHEiPD098c4772DWrFlWfz9ESiaIBSPkiIgU7vr16wgICMBnn32GN99809blEJGVcUwKERERKRJDChERESkSQwoREREpkk1Dyp9//om+ffuiSpUqEAQBW7duNdoviiJmzZoFX19faLVahISEPLI+QnJyMkJDQ+Hq6gp3d3e88soryMjIKMF3QUQlpWCpe45HISofbBpSClZr/PrrrwvdP3/+fCxatAjLli1DVFQUnJ2d0aNHD6P1GEJDQ3H27FlERERg+/bt+PPPP7n4ERERURmgmNk9giBgy5YthjUJRFFElSpVMG3aNMNvTampqfD29kZ4eDgGDx6M8+fPo379+oiOjjbc5nznzp145plncPPmTVSpUsVWb4eIiIgspNh1UmJiYpCQkGC0gqObmxtat26NgwcPYvDgwTh48CDc3d0NAQWQlqVWqVSIiopC//79C712Tk6O0SqYer0eycnJ8PDwKHLZbiIiInqUKIpIT09HlSpVjBY0lINiQ0pCQgIAPLLokbe3t2FfQkICvLy8jPZrNBpUqlTJcExh5syZg9mzZ8tcMRERUfkVFxeHatWqyXpNxYYUa5o5cyamTp1qeJ6amorq1asjLi7OcKdTIiJr2rcPePZZea51/z4g8y+wRMWWlpYGPz8/VKhQQfZrKzakFNwWPjEx0Wip68TERMNdQ318fJCUlGR0Xn5+PpKTkwu9rXwBBwcHODg4PLLd1dWVIYWISkTLllKw0OvNv4YgAEFBgLu7bGURmc0awyUUm70DAgLg4+ODyMhIw7a0tDRERUWhTZs2AIA2bdogJSUFR48eNRyze/du6PV6tG7dusRrJiIqLh8f4LnnAI2FvypOmCBPPURKZNOWlIyMDFy5csXwPCYmBidOnEClSpVQvXp1TJ48GR9//DECAwMREBCA9957D1WqVDHMAAoKCkLPnj0xZswYLFu2DHl5eZgwYQIGDx7MmT1E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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "render_history(hist, skip_frames=50)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Test manual behavior for an agent\n", + "\n", + "Need to set all of its behaviors to manual." + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [], + "source": [ + "ag_idx = 9\n", + "manual_behaviors = jnp.array([Behaviors.MANUAL.value, Behaviors.MANUAL.value,])\n", + "manual_color = jnp.array([0., 0., 0.])\n", + "manual_motors = jnp.array([1., 1.])\n", + "\n", + "behaviors = state.agents.behavior.at[ag_idx].set(manual_behaviors)\n", + "colors = state.agents.color.at[ag_idx].set(manual_color)\n", + "motors = state.agents.motor.at[ag_idx].set(manual_motors)\n", + "\n", + "agents = state.agents.replace(behavior=behaviors, color=colors, motor=motors)\n", + "state = state.replace(agents=agents)" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [], + "source": [ + "hist = []\n", + "\n", + "for i in range(n_steps):\n", + " state = env.step(state)\n", + " hist.append(state)" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAikAAAIjCAYAAADGCIt4AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAABoUElEQVR4nO3dZ3hU1f728e+U9JCEmoQOEgSk9yqIUZoogiLIEbCARwFFrOjfgg2wHaULKlhQbKBgATE0UYTQqzRDlRAgJCFA2sx+XszDaCRAykxmJrk/55rrMLus/GZzTuZmrbXXNhmGYSAiIiLiZcyeLkBEREQkLwopIiIi4pUUUkRERMQrKaSIiIiIV1JIEREREa+kkCIiIiJeSSFFREREvJJCioiIiHglhRQRERHxSgopIiXI0KFDqVmzpqfLEBFxCYUUES9nMpny9VqxYoWnS72iadOmMWfOHE+XcUXDhg3DZDJx0003XbQvPT2d0aNHU7VqVQICAqhfvz7Tp0+/6Lg5c+Zc8u8qMTHxouMXLlxI8+bNCQwMpHr16jz//PPk5OS45fOJ+AqrpwsQkcv7+OOPc73/6KOPWLp06UXb69evz6xZs7Db7cVZXoFMmzaNChUqMHToUE+Xcknr169nzpw5BAYGXrTPZrPRrVs31q9fz4gRI4iJiWHJkiU8+OCDnD59mqeffvqic1588UVq1aqVa1tERESu9z/++CN9+vShS5cuTJ48mW3btvHyyy+TlJSUZwASKTUMEfEpI0aMMHz1/7rXXHON0blzZ0+XcUl2u91o166dcc899xg1atQwevXqlWv/F198YQDG+++/n2t7v379jMDAQOP48ePObbNnzzYAIz4+/oo/t0GDBkaTJk2M7Oxs57ZnnnnGMJlMxq5du4r4qUR8l4Z7REqQf89JOXDgACaTiTfeeIOpU6dSu3ZtgoODufHGGzl8+DCGYfDSSy9RtWpVgoKCuOWWW0hOTr6o3R9//JFOnToREhJCmTJl6NWrFzt27Mh1TGJiInfffbdzGCQ6OppbbrmFAwcOAFCzZk127NjBypUrncMeXbp0cZ6fkpLC6NGjqVatGgEBAdSpU4eJEyfm6hn65+f53//+R40aNQgKCqJz585s3749Vz3Z2dn88ccfHDt2LN/X7+OPP2b79u288soree7/5ZdfABgwYECu7QMGDCAjI4Nvv/02z/POnDmDzWbLc9/OnTvZuXMnw4cPx2r9u3P7wQcfxDAMvvrqq3zXL1LSaLhHpBSYO3cuWVlZjBo1iuTkZF577TX69+9P165dWbFiBU8++ST79u1j8uTJPPbYY3zwwQfOcz/++GOGDBlCt27dmDhxIufOnWP69Ol07NiRTZs2OUNRv3792LFjB6NGjaJmzZokJSWxdOlSDh06RM2aNXn77bcZNWoUoaGhPPPMMwBERkYCcO7cOTp37szRo0e5//77qV69Or/99htjx47l2LFjvP3227k+z0cffcSZM2cYMWIEGRkZvPPOO3Tt2pVt27Y52zx69Cj169dnyJAh+ZoHc+bMGZ588kmefvppoqKi8jwmMzMTi8WCv79/ru3BwcEAbNiwgWHDhuXad91115Geno6/vz/dunXjzTffJCYmxrl/06ZNALRs2TLXeZUrV6Zq1arO/SKlkqe7ckSkYC433DNkyBCjRo0azvcJCQkGYFSsWNFISUlxbh87dqwBXDTEMHDgQMPf39/IyMgwDMMwzpw5Y0RERBjDhg3L9XMSExON8PBw5/bTp08bgPH6669ftvZLDfe89NJLRkhIiLFnz55c25966inDYrEYhw4dyvV5goKCjCNHjjiPW7t2rQEYjzzyyEWffciQIZet6YLHHnvMqFWrlvOz5zXc8+abbxqA8csvv1xUJ2DcdNNNzm2ff/65MXToUOPDDz80FixYYPzf//2fERwcbFSoUMH5eQzDMF5//XUDyLXtglatWhlt27bNV/0iJZGGe0RKgdtvv53w8HDn+zZt2gDwn//8J9cQQ5s2bcjKyuLo0aMALF26lJSUFAYOHMjJkyedL4vFQps2bVi+fDkAQUFB+Pv7s2LFCk6fPl3g+r788ks6depE2bJlc/2c2NhYbDYbq1atynV8nz59qFKlivN969atadOmDT/88INzW82aNTEMI1+9KHv27OGdd97h9ddfJyAg4JLH3XnnnYSHh3PPPfewdOlSDhw4wMyZM5k2bRoA58+fdx7bv39/Zs+ezeDBg+nTpw8vvfQSS5Ys4dSpU7mGky6ck9fPDQwMzNWmSGmj4R6RUqB69eq53l8ILNWqVctz+4WgsXfvXgC6du2aZ7thYWGA4wt24sSJPProo0RGRtK2bVtuuukmBg8efMmhk3/au3cvW7dupWLFinnuT0pKyvX+n8MlF9StW5cvvvjiij8rLw8//DDt27enX79+lz0uKiqKhQsXctddd3HjjTcCjmswefJkhgwZQmho6GXP79ixI23atOHnn392bgsKCgIcQ0n/lpGR4dwvUhoppIiUAhaLpUDbDcMAcE5a/fjjj/MMG//shRk9ejS9e/fmm2++YcmSJTz77LOMHz+eZcuW0axZs8vWZ7fbueGGG3jiiSfy3F+3bt3Lnl8Uy5YtY/HixcyfP985yRcgJyeH8+fPc+DAAcqVK+cMZNdeey1//vkn27Zt4+zZszRp0oS//vor33VWq1aN3bt3O99HR0cDcOzYsYtC47Fjx2jdunVRP6KIz1JIEZFLuuqqqwCoVKkSsbGx+Tr+0Ucf5dFHH2Xv3r00bdqUN998k08++QRwLEx3qfPS09Pz9TPg7x6ef9qzZ0+hVts9dOgQAH379r1o39GjR6lVqxb/+9//GD16tHO7xWKhadOmzvcXekbyU/+ff/6Zq8foQjvr16/PFUj++usvjhw5wvDhwwvycURKFM1JEZFL6tatG2FhYbz66qtkZ2dftP/EiROA4+6cjIyMXPuuuuoqypQpk2sYIyQkhJSUlIva6d+/P2vWrGHJkiUX7UtJSblo5dVvvvnGOW8GYN26daxdu5YePXo4t+X3FuSuXbuyYMGCi14VK1akZcuWLFiwgN69e1/y/BMnTjBx4kQaN26cK6RcuDb/9MMPP7Bhwwa6d+/u3HbNNddQr149Zs6cmes25enTp2MymbjtttsuW79ISaaeFBG5pLCwMKZPn85dd91F8+bNGTBgABUrVuTQoUN8//33dOjQgSlTprBnzx6uv/56+vfvT4MGDbBarSxYsIDjx4/nWlOkRYsWTJ8+nZdffpk6depQqVIlunbtyuOPP87ChQu56aabGDp0KC1atODs2bNs27aNr776igMHDlChQgVnO3Xq1KFjx4488MADZGZm8vbbb1O+fPlcw0X5vQW5evXqF83ZAcfwVWRkJH369Mm1vXPnzrRr1446deqQmJjIzJkzSU9P57vvvsNs/vvffe3bt6dZs2a0bNmS8PBwNm7cyAcffEC1atUuWpn29ddf5+abb+bGG29kwIABbN++nSlTpnDfffdRv379/P51iZQ4Cikicll33nknlStXZsKECbz++utkZmZSpUoVOnXqxN133w045lkMHDiQuLg4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4vd7f6d+xfrFVaJ4GYUUEREpFiaTiSc7Psmm+zdxd9O7CbQEYsKE1WzFz+yHxeRYHvaqclfxTvd32DlipwJKKWcyjKI82LpkSEtLIzw8nNTUVMLCwjxdjohIqZCSkcKCXQs4ln6M89nniQiMoHl0c7rU7KJJsj7End+hWsxNREQ8IiIwgrub3e3pMsSLabhHREREvJJCioiIiHglhRQRERHxSgopIiIi4pUUUkRERMQrKaSIiIiIV1JIEREREa+kkCIiIiJeSSFFREREvJLXh5SjR4/yn//8h/LlyxMUFESjRo1Yv369c79hGDz33HNER0cTFBREbGwse/fu9WDFIiIi4gpeHVJOnz5Nhw4d8PPz48cff2Tnzp28+eablC1b1nnMa6+9xqRJk5gxYwZr164lJCSEbt26kZGR4cHKRUREpKi8+gGDTz31FL/++iu//PJLnvsNw6By5co8+uijPPbYYwCkpqYSGRnJnDlzGDBgQL5+jh4wKCIiUjju/A716p6UhQsX0rJlS26//XYqVapEs2bNmDVrlnN/QkICiYmJxMbGOreFh4fTpk0b1qxZc8l2MzMzSUtLy/USERER7+LVIeXPP/9k+vTpxMTEsGTJEh544AEeeughPvzwQwASExMBiIyMzHVeZGSkc19exo8fT3h4uPNVrVo1930IERERKRSvDil2u53mzZvz6quv0qxZM4YPH86wYcOYMWNGkdodO3Ysqampztfhw4ddVLGIiIi4ileHlOjoaBo0aJBrW/369Tl06BAAUVFRABw/fjzXMcePH3fuy0tAQABhYWG5XiIiIuJdvDqkdOjQgd27d+fatmfPHmrUqAFArVq1iIqKIi4uzrk/LS2NtWvX0q5du2KtVURERFzL6ukCLueRRx6hffv2vPrqq/Tv359169Yxc+ZMZs6cCYDJZGL06NG8/PLLxMTEUKtWLZ599lkqV65Mnz59PFu8iIiIFIlXh5RWrVqxYMECxo4dy4svvkitWrV4++23GTRokPOYJ554grNnzzJ8+HBSUlLo2LEjixcvJjAw0IOVi4iISFF59TopxUXrpIiIiBROqV0nRUREREovrx7uEREREccK6znnczDsBn4hfphMJk+XVCwUUkRERLyQYRgcXHWQ+Knx7P52N7YsGwBmq5naN9Sm9cjWXNXtKsyWkjsoopAiIiLiZQ6uOsii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W281jh075rmiS6B/hxRdc9dbtGiR0bBhQyMgIMCoV6+eMXPmzFz77Xa78eyzzxqRkZFGQECAcf311xu7d+/2ULW+Ly0tzXj44YeN6tWrG4GBgUbt2rWNZ555xsjMzHQeo2teNMuXL8/z9/eQIUMMw8jf9T116pQxcOBAIzQ01AgLCzPuvvtu48yZMwWqw2QY/1iiT0RERMRLlNo5KSIiIuLdFFJERETEKymkiIiIiFdSSBERERGvpJAiIiIiXkkhRURERLySQoqIiIh4JYUUERER8UoKKSLic+bMmUNERMQVjzOZTHzzzTdur0dE3EMhRUQuyWaz0b59e/r27Ztre2pqKtWqVeOZZ5655LldunTBZDJhMpkIDAykQYMGTJs2zSV13XHHHezZs8f5/oUXXqBp06YXHXfs2DF69Ojhkp8pIsVPIUVELslisTBnzhwWL17M3LlzndtHjRpFuXLleP755y97/rBhwzh27Bg7d+6kf//+jBgxgs8++6zIdQUFBVGpUqUrHhcVFUVAQECRf56IeIZCiohcVt26dZkwYQKjRo3i2LFjfPvtt8ybN4+PPvoIf3//y54bHBxMVFQUtWvX5oUXXiAmJoaFCxcCcOjQIW655RZCQ0MJCwujf//+HD9+3Hnuli1buO666yhTpgxhYWG0aNGC9evXA7mHe+bMmcO4cePYsmWLs+dmzpw5wMXDPdu2baNr164EBQVRvnx5hg8fTnp6unP/0KFD6dOnD2+88QbR0dGUL1+eESNGkJ2d7YIrKSIFZfV0ASLi/UaNGsWCBQu466672LZtG8899xxNmjQpcDtBQUFkZWVht9udAWXlypXk5OQwYsQI7rjjDlasWAHAoEGDaNasGdOnT8disbB582b8/PwuavOOO+5g+/btLF68mJ9//hmA8PDwi447e/Ys3bp1o127dsTHx5OUlMR9993HyJEjnaEGYPny5URHR7N8+XL27dvHHXfcQdOmTRk2bFiBP6+IFI1CiohckclkYvr06dSvX59GjRrx1FNPFeh8m83GZ599xtatWxk+fDhxcXFs27aNhIQEqlWrBsBHH33ENddcQ3x8PK1ateLQoUM8/vjj1KtXD4CYmJg82w4KCiI0NBSr1UpUVNQla/j000/JyMjgo48+IiQkBIApU6bQu3dvJk6cSGRkJABly5ZlypQpWCwW6tWrR69evYiLi1NIEfEADfeISL588MEHBAcHk5CQwJEjR/J1zrRp0wgNDSUoKIhhw4bxyCOP8MADD7Br1y6qVavmDCgADRo0ICIigl27dgEwZswY7rvvPmJjY5kwYQL79+8vUv27du2iSZMmzoAC0KFDB+x2O7t373Zuu+aaa7BYLM730dHRJCUlFelni0jhKKSIyBX99ttv/O9//+O7776jdevW3HvvvRiGccXzBg0axObNm0lISODs2bO89dZbmM35+7XzwgsvsGPHDnr16sWyZcto0KABCxYsKOpHuaJ/DymZTCbsdrvbf66IXEwhRUQu69y5cwwdOpQHHniA6667jvfff59169YxY8aMK54bHh5OnTp1qFKlSq5wUr9+fQ4fPszhw4ed23bu3ElKSgoNGjRwbqtbty6PPPIIP/30E3379mX27Nl5/hx/f39sNttla6lfvz5btmzh7Nmzzm2//vorZrOZq6+++oqfRUSKn0KKiFzW2LFjMQyDCRMmAFCzZk3eeOMNnnjiCQ4cOFCoNmNjY2nUqBGDBg1i48aNrFu3jsGDB9O5c2datmzJ+fPnGTlyJCtWrODgwYP8+uuvxMfHU79+/Tzbq1mzJgkJCWzevJmTJ0+SmZl50TGDBg0iMDCQIUOGsH37dpYvX86oUaO46667nPNRRMS7KKSIyCWtXLmSqVOnMnv2bIKDg53b77//ftq3b5/vYZ9/M5lMfPvtt5QtW5Zrr72W2NhYateuzeeffw441mc5deoUgwcPpm7duvTv358ePXowbty4PNvr168f3bt357rrrqNixYp5rsUSHBzMkiVLSE5OplWrVtx2221cf/31TJkypcD1i0jxMBmF+Q0jIiIi4mbqSRERERGvpJAiIiIiXkkhRURERLySQoqIiIh4JYUUERER8UoKKSIiIuKVFFJERETEKymkiIiIiFdSSBERERGvpJAiIiIiXkkhRURERLzS/wNTj48akyB5BAAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "render_history(hist, skip_frames=50)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "venv", + "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.10.12" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/vivarium/experimental/notebooks/selective_sensors.ipynb b/vivarium/experimental/notebooks/selective_sensors.ipynb deleted file mode 100644 index aee523f..0000000 --- a/vivarium/experimental/notebooks/selective_sensors.ipynb +++ /dev/null @@ -1,814 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Quick tutorial to explain how to create a environment with braitenberg vehicles equiped with selective sensors (still a draft so comments of the notebook won't be complete yet)" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "2024-07-09 15:48:58.727097: W external/xla/xla/service/gpu/nvptx_compiler.cc:760] The NVIDIA driver's CUDA version is 12.2 which is older than the ptxas CUDA version (12.5.40). Because the driver is older than the ptxas version, XLA is disabling parallel compilation, which may slow down compilation. You should update your NVIDIA driver or use the NVIDIA-provided CUDA forward compatibility packages.\n" - ] - } - ], - "source": [ - "import logging as lg\n", - "\n", - "from enum import Enum\n", - "from functools import partial\n", - "from typing import Tuple\n", - "\n", - "import numpy as np\n", - "import jax.numpy as jnp\n", - "\n", - "from jax import vmap, jit\n", - "from jax import random, ops, lax\n", - "\n", - "from flax import struct\n", - "from jax_md.rigid_body import RigidBody\n", - "from jax_md import simulate \n", - "from jax_md import space, rigid_body, partition, quantity\n", - "\n", - "from vivarium.experimental.environments.utils import normal, distance \n", - "from vivarium.experimental.environments.base_env import BaseState, BaseEnv\n", - "from vivarium.experimental.environments.physics_engine import total_collision_energy, friction_force, dynamics_fn\n", - "from vivarium.experimental.environments.braitenberg.simple import relative_position, proximity_map, sensor_fn, sensor\n", - "from vivarium.experimental.environments.braitenberg.simple import Behaviors, behavior_to_params, linear_behavior\n", - "from vivarium.experimental.environments.braitenberg.simple import lr_2_fwd_rot, fwd_rot_2_lr, motor_command\n", - "from vivarium.experimental.environments.braitenberg.simple import braintenberg_force_fn" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Create the classes and helper functions" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Add entity sensed type as a field in entities + sensed in agents. The agents sense the \"sensed type\" of the entities. In our case, there will be preys, predators, ressources and poison." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "\n", - "### Define the constants and the classes of the environment to store its state ###\n", - "SPACE_NDIMS = 2\n", - "\n", - "class EntityType(Enum):\n", - " AGENT = 0\n", - " OBJECT = 1\n", - "\n", - "class EntitySensedType(Enum):\n", - " PREY = 0\n", - " PRED = 1\n", - " RESSOURCE = 2\n", - " POISON = 3\n", - "\n", - "# Already incorporates position, momentum, force, mass and velocity\n", - "@struct.dataclass\n", - "class EntityState(simulate.NVEState):\n", - " entity_type: jnp.array\n", - " ent_sensed_type: jnp.array\n", - " entity_idx: jnp.array\n", - " diameter: jnp.array\n", - " friction: jnp.array\n", - " exists: jnp.array\n", - " \n", - "@struct.dataclass\n", - "class ParticleState:\n", - " ent_idx: jnp.array\n", - " color: jnp.array\n", - "\n", - "@struct.dataclass\n", - "class AgentState(ParticleState):\n", - " prox: jnp.array\n", - " motor: jnp.array\n", - " proximity_map_dist: jnp.array\n", - " proximity_map_theta: jnp.array\n", - " behavior: jnp.array\n", - " params: jnp.array\n", - " sensed: jnp.array\n", - " wheel_diameter: jnp.array\n", - " speed_mul: jnp.array\n", - " max_speed: jnp.array\n", - " theta_mul: jnp.array \n", - " proxs_dist_max: jnp.array\n", - " proxs_cos_min: jnp.array\n", - "\n", - "@struct.dataclass\n", - "class ObjectState(ParticleState):\n", - " pass\n", - "\n", - "@struct.dataclass\n", - "class State(BaseState):\n", - " max_agents: jnp.int32\n", - " max_objects: jnp.int32\n", - " neighbor_radius: jnp.float32\n", - " dt: jnp.float32 # Give a more explicit name\n", - " collision_alpha: jnp.float32\n", - " collision_eps: jnp.float32\n", - " entities: EntityState\n", - " agents: AgentState\n", - " objects: ObjectState " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Define get_relative_displacement" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "# TODO : Refactor the code bc pretty ugly to have 4 arguments returned here\n", - "def get_relative_displacement(state, agents_neighs_idx, displacement_fn):\n", - " body = state.entities.position\n", - " senders, receivers = agents_neighs_idx\n", - " Ra = body.center[senders]\n", - " Rb = body.center[receivers]\n", - " dR = - space.map_bond(displacement_fn)(Ra, Rb) # Looks like it should be opposite, but don't understand why\n", - "\n", - " dist, theta = proximity_map(dR, body.orientation[senders])\n", - " proximity_map_dist = jnp.zeros((state.agents.ent_idx.shape[0], state.entities.entity_idx.shape[0]))\n", - " proximity_map_dist = proximity_map_dist.at[senders, receivers].set(dist)\n", - " proximity_map_theta = jnp.zeros((state.agents.ent_idx.shape[0], state.entities.entity_idx.shape[0]))\n", - " proximity_map_theta = proximity_map_theta.at[senders, receivers].set(theta)\n", - " return dist, theta, proximity_map_dist, proximity_map_theta\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "to compute motors, only use linear behaviors (don't vmap it) because we vmap the functions to compute agents proxiemters and motors at a higher level \n" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [], - "source": [ - "def compute_motor(proxs, params, behaviors, motors):\n", - " \"\"\"Compute new motor values. If behavior is manual, keep same motor values. Else, compute new values with proximeters and params.\n", - "\n", - " :param proxs: proximeters of all agents\n", - " :param params: parameters mapping proximeters to new motor values\n", - " :param behaviors: array of behaviors\n", - " :param motors: current motor values\n", - " :return: new motor values\n", - " \"\"\"\n", - " manual = jnp.where(behaviors == Behaviors.MANUAL.value, 1, 0)\n", - " manual_mask = manual\n", - " linear_motor_values = linear_behavior(proxs, params)\n", - " motor_values = linear_motor_values * (1 - manual_mask) + motors * manual_mask\n", - " return motor_values" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Add Mask sensors and don't change functions\n", - "\n", - "- mask_sensors: mask sensors according to sensed entity type for an agent\n", - "- don't change: return agent raw_proxs (surely return either the masked or the same prox array according to a sensed e type)\n", - "\n", - "Then for each agent, we iterate on all of his behaviors. For each behavior, we iterate on each possible sensed entity type. If the entity is sensed, we keep the raw proximeters of the agent as they are currently. If it is not, we mask the proximeters of the specific (non sensed) entity type." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [], - "source": [ - "def mask_sensors(state, agent_raw_proxs, ent_type_id, ent_target_idx):\n", - " mask = jnp.where(state.entities.ent_sensed_type[ent_target_idx] == ent_type_id, 0, 1)\n", - " mask = jnp.expand_dims(mask, 1)\n", - " mask = jnp.broadcast_to(mask, agent_raw_proxs.shape)\n", - " return agent_raw_proxs * mask\n", - "\n", - "def dont_change(state, agent_raw_proxs, ent_type_id, ent_target_idx):\n", - " return agent_raw_proxs" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Add compute_behavior_prox, compute_behavior_proxs_motors, compute_agent_proxs_motors\n", - "\n", - "- compute_behavior_prox: compute the proxs for one behavior (enumerate through all the sensed entities on this particular behavior)\n", - "- compute_behavior_proxs_motors: use fn above to compute the proxs and compute the motor values according to the behavior\n", - "- #vmap compute_all_behavior_proxs_motors: computes this for all the behaviors of an agent\n", - "- compute_agent_proxs_motors: compute the proximeters and motor values of an agent for all its behaviors. Just return mean motor value\n", - "- #vmap compute_all_agents_proxs_motors: computes this for all agents (vmap over params, sensed and agent_raw_proxs) " - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [], - "source": [ - "# TODO : Use a fori_loop on this later\n", - "def compute_behavior_prox(state, agent_raw_proxs, ent_target_idx, sensed_entities):\n", - " for ent_type_id, sensed in enumerate(sensed_entities):\n", - " # need the lax.cond because you don't want to change the proxs if you perceive the entity\n", - " # but you want to mask the raw proxs if you don't detect it\n", - " agent_raw_proxs = lax.cond(sensed, dont_change, mask_sensors, state, agent_raw_proxs, ent_type_id, ent_target_idx)\n", - " proxs = jnp.max(agent_raw_proxs, axis=0)\n", - " return proxs\n", - "\n", - "def compute_behavior_proxs_motors(state, params, sensed, behavior, motor, agent_raw_proxs, ent_target_idx):\n", - " behavior_prox = compute_behavior_prox(state, agent_raw_proxs, ent_target_idx, sensed)\n", - " behavior_motors = compute_motor(behavior_prox, params, behavior, motor)\n", - " return behavior_prox, behavior_motors\n", - "\n", - "# vmap on params, sensed and behavior (parallelize on all agents behaviors at once, but not motorrs because are the same)\n", - "compute_all_behavior_proxs_motors = vmap(compute_behavior_proxs_motors, in_axes=(None, 0, 0, 0, None, None, None))\n", - "\n", - "def compute_agent_proxs_motors(state, agent_idx, params, sensed, behavior, motor, raw_proxs, ag_idx_dense_senders, ag_idx_dense_receivers):\n", - " behavior = jnp.expand_dims(behavior, axis=1)\n", - " ent_ag_idx = ag_idx_dense_senders[agent_idx]\n", - " ent_target_idx = ag_idx_dense_receivers[agent_idx]\n", - " agent_raw_proxs = raw_proxs[ent_ag_idx]\n", - "\n", - " # vmap on params, sensed, behaviors and motorss (vmap on all agents)\n", - " agent_proxs, agent_motors = compute_all_behavior_proxs_motors(state, params, sensed, behavior, motor, agent_raw_proxs, ent_target_idx)\n", - " mean_agent_motors = jnp.mean(agent_motors, axis=0)\n", - "\n", - " return agent_proxs, mean_agent_motors\n", - "\n", - "compute_all_agents_proxs_motors = vmap(compute_agent_proxs_motors, in_axes=(None, 0, 0, 0, 0, 0, None, None, None))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Add classical braitenberg force fn" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Create the main environment class" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [], - "source": [ - "\n", - "#--- 4 Define the environment class with its different functions (step ...) ---#\n", - "class SelectiveSensorsEnv(BaseEnv):\n", - " def __init__(self, state, seed=42):\n", - " self.seed = seed\n", - " self.init_key = random.PRNGKey(seed)\n", - " self.displacement, self.shift = space.periodic(state.box_size)\n", - " self.init_fn, self.apply_physics = dynamics_fn(self.displacement, self.shift, braintenberg_force_fn)\n", - " self.neighbor_fn = partition.neighbor_list(\n", - " self.displacement, \n", - " state.box_size,\n", - " r_cutoff=state.neighbor_radius,\n", - " dr_threshold=10.,\n", - " capacity_multiplier=1.5,\n", - " format=partition.Sparse\n", - " )\n", - "\n", - " self.neighbors = self.allocate_neighbors(state)\n", - " # self.neighbors, self.agents_neighs_idx = self.allocate_neighbors(state)\n", - "\n", - " def distance(self, point1, point2):\n", - " return distance(self.displacement, point1, point2)\n", - " \n", - " ### Add ag_idx_dense !!! \n", - " @partial(jit, static_argnums=(0,))\n", - " def _step(self, state: State, neighbors: jnp.array, agents_neighs_idx: jnp.array, ag_idx_dense: jnp.array) -> Tuple[State, jnp.array]:\n", - " # Differences : compute raw proxs for all agents first \n", - " dist, relative_theta, proximity_dist_map, proximity_dist_theta = get_relative_displacement(state, agents_neighs_idx, displacement_fn=self.displacement)\n", - " senders, receivers = agents_neighs_idx\n", - "\n", - " dist_max = state.agents.proxs_dist_max[senders]\n", - " cos_min = state.agents.proxs_cos_min[senders]\n", - " targer_exist_mask = state.entities.exists[agents_neighs_idx[1, :]]\n", - " raw_proxs = sensor_fn(dist, relative_theta, dist_max, cos_min, targer_exist_mask)\n", - "\n", - " # 2: Use dense idx for neighborhoods to vmap all of this\n", - " # TODO : Could even just pass ag_idx_dense in the fn and do this inside\n", - " ag_idx_dense_senders, ag_idx_dense_receivers = ag_idx_dense\n", - "\n", - " agent_proxs, mean_agent_motors = compute_all_agents_proxs_motors(\n", - " state,\n", - " state.agents.ent_idx,\n", - " state.agents.params,\n", - " state.agents.sensed,\n", - " state.agents.behavior,\n", - " state.agents.motor,\n", - " raw_proxs,\n", - " ag_idx_dense_senders,\n", - " ag_idx_dense_receivers,\n", - " )\n", - "\n", - " agents = state.agents.replace(\n", - " prox=agent_proxs, \n", - " proximity_map_dist=proximity_dist_map, \n", - " proximity_map_theta=proximity_dist_theta,\n", - " motor=mean_agent_motors\n", - " )\n", - "\n", - " # Last block unchanged\n", - " state = state.replace(agents=agents)\n", - " entities = self.apply_physics(state, neighbors)\n", - " state = state.replace(time=state.time+1, entities=entities)\n", - " neighbors = neighbors.update(state.entities.position.center)\n", - "\n", - " return state, neighbors\n", - " \n", - " def step(self, state: State) -> State:\n", - " if state.entities.momentum is None:\n", - " state = self.init_fn(state, self.init_key)\n", - " \n", - " current_state = state\n", - " state, neighbors = self._step(current_state, self.neighbors, self.agents_neighs_idx, self.agents_idx_dense)\n", - "\n", - " if self.neighbors.did_buffer_overflow:\n", - " # reallocate neighbors and run the simulation from current_state\n", - " lg.warning(f'NEIGHBORS BUFFER OVERFLOW at step {state.time}: rebuilding neighbors')\n", - " neighbors = self.allocate_neighbors(state)\n", - " assert not neighbors.did_buffer_overflow\n", - "\n", - " self.neighbors = neighbors\n", - " return state\n", - " \n", - " def allocate_neighbors(self, state, position=None):\n", - " position = state.entities.position.center if position is None else position\n", - " neighbors = self.neighbor_fn.allocate(position)\n", - "\n", - " # Also update the neighbor idx of agents (not the cleanest to attribute it to with self here)\n", - " ag_idx = state.entities.entity_type[neighbors.idx[0]] == EntityType.AGENT.value\n", - " self.agents_neighs_idx = neighbors.idx[:, ag_idx]\n", - " agents_idx_dense_senders = jnp.array([jnp.argwhere(jnp.equal(self.agents_neighs_idx[0, :], idx)).flatten() for idx in jnp.arange(state.max_agents)])\n", - " # agents_idx_dense_receivers = jnp.array([jnp.argwhere(jnp.equal(self.agents_neighs_idx[1, :], idx)).flatten() for idx in jnp.arange(self.max_agents)])\n", - " agents_idx_dense_receivers = self.agents_neighs_idx[1, :][agents_idx_dense_senders]\n", - " # self.agents_idx_dense = jnp.array([jnp.where(self.agents_neighs_idx[0, :] == idx).flatten() for idx in range(self.max_agents)])\n", - " self.agents_idx_dense = agents_idx_dense_senders, agents_idx_dense_receivers\n", - " return neighbors" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Create the state" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [], - "source": [ - "seed = 0\n", - "max_agents = 10\n", - "max_objects = 10\n", - "n_dims = 2\n", - "box_size = 100\n", - "diameter = 5.0\n", - "friction = 0.1\n", - "mass_center = 1.0\n", - "mass_orientation = 0.125\n", - "neighbor_radius = 100.0\n", - "collision_alpha = 0.5\n", - "collision_eps = 0.1\n", - "dt = 0.1\n", - "wheel_diameter = 2.0\n", - "speed_mul = 1.0\n", - "max_speed = 10.0\n", - "theta_mul = 1.0\n", - "prox_dist_max = 40.0\n", - "prox_cos_min = 0.0\n", - "behavior = Behaviors.AGGRESSION.value\n", - "behaviors=Behaviors.AGGRESSION.value\n", - "existing_agents = None\n", - "existing_objects = None\n", - "\n", - "n_preys = 5\n", - "n_preds = 5\n", - "n_ress = 5\n", - "n_pois = 5\n", - "\n", - "key = random.PRNGKey(seed)\n", - "key, key_agents_pos, key_objects_pos, key_orientations = random.split(key, 4)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Entities" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [], - "source": [ - "existing_agents = max_agents if not existing_agents else existing_agents\n", - "existing_objects = max_objects if not existing_objects else existing_objects\n", - "\n", - "n_entities = max_agents + max_objects # we store the entities data in jax arrays of length max_agents + max_objects \n", - "# Assign random positions to each entity in the environment\n", - "agents_positions = random.uniform(key_agents_pos, (max_agents, n_dims)) * box_size\n", - "objects_positions = random.uniform(key_objects_pos, (max_objects, n_dims)) * box_size\n", - "positions = jnp.concatenate((agents_positions, objects_positions))\n", - "# Assign random orientations between 0 and 2*pi to each entity\n", - "orientations = random.uniform(key_orientations, (n_entities,)) * 2 * jnp.pi\n", - "# Assign types to the entities\n", - "agents_entities = jnp.full(max_agents, EntityType.AGENT.value)\n", - "object_entities = jnp.full(max_objects, EntityType.OBJECT.value)\n", - "entity_types = jnp.concatenate((agents_entities, object_entities), dtype=int)\n", - "# Define arrays with existing entities\n", - "exists_agents = jnp.concatenate((jnp.ones((existing_agents)), jnp.zeros((max_agents - existing_agents))))\n", - "exists_objects = jnp.concatenate((jnp.ones((existing_objects)), jnp.zeros((max_objects - existing_objects))))\n", - "exists = jnp.concatenate((exists_agents, exists_objects), dtype=int)\n", - "\n", - "### TODO : Actually find a way to init this later\n", - "sensed_ent_types = jnp.concatenate([\n", - " jnp.full(n_preys, EntitySensedType.PREY.value),\n", - " jnp.full(n_preds, EntitySensedType.PRED.value),\n", - " jnp.full(n_ress, EntitySensedType.RESSOURCE.value),\n", - " jnp.full(n_pois, EntitySensedType.POISON.value),\n", - "])\n", - "\n", - "ent_sensed_types = jnp.zeros(n_entities)\n", - "\n", - "entities = EntityState(\n", - " position=RigidBody(center=positions, orientation=orientations),\n", - " momentum=None,\n", - " force=RigidBody(center=jnp.zeros((n_entities, 2)), orientation=jnp.zeros(n_entities)),\n", - " mass=RigidBody(center=jnp.full((n_entities, 1), mass_center), orientation=jnp.full((n_entities), mass_orientation)),\n", - " entity_type=entity_types,\n", - " ent_sensed_type=sensed_ent_types,\n", - " entity_idx = jnp.array(list(range(max_agents)) + list(range(max_objects))),\n", - " diameter=jnp.full((n_entities), diameter),\n", - " friction=jnp.full((n_entities), friction),\n", - " exists=exists\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Agents" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "(5, 2, 2, 3) (5, 2, 4)\n", - "(5, 2, 2, 3) (5, 2, 4)\n", - "(10, 2, 2, 3) (10, 2, 4) (10, 2)\n" - ] - } - ], - "source": [ - "# Prey behaviors\n", - "love = behavior_to_params(Behaviors.LOVE.value)\n", - "fear = behavior_to_params(Behaviors.FEAR.value)\n", - "sensed_love = jnp.array([1, 0, 1, 0])\n", - "sensed_fear = jnp.array([0, 1, 0, 1])\n", - "prey_params = jnp.array([love, fear])\n", - "prey_sensed = jnp.array([sensed_love, sensed_fear])\n", - "\n", - "# Do like if we had batches of params and sensed entities for all agents\n", - "prey_batch_params = jnp.tile(prey_params[None], (n_preys, 1, 1 ,1))\n", - "prey_batch_sensed = jnp.tile(prey_sensed[None], (n_preys, 1, 1))\n", - "print(prey_batch_params.shape, prey_batch_sensed.shape)\n", - "\n", - "prey_behaviors = jnp.array([Behaviors.LOVE.value, Behaviors.FEAR.value])\n", - "prey_batch_behaviors = jnp.tile(prey_behaviors[None], (n_preys, 1))\n", - "\n", - "# Pred behaviors\n", - "aggr = behavior_to_params(Behaviors.AGGRESSION.value)\n", - "fear = behavior_to_params(Behaviors.FEAR.value)\n", - "sensed_aggr = jnp.array([1, 0, 0, 0])\n", - "sensed_fear = jnp.array([0, 0, 0, 1])\n", - "pred_params = jnp.array([aggr, fear])\n", - "pred_sensed = jnp.array([sensed_aggr, sensed_fear])\n", - "\n", - "# Do like if we had batches of params and sensed entities for all agents\n", - "pred_batch_params = jnp.tile(pred_params[None], (n_preys, 1, 1 ,1))\n", - "pred_batch_sensed = jnp.tile(pred_sensed[None], (n_preys, 1, 1))\n", - "print(pred_batch_params.shape, pred_batch_sensed.shape)\n", - "\n", - "pred_behaviors = jnp.array([Behaviors.AGGRESSION.value, Behaviors.FEAR.value])\n", - "pred_batch_behaviors = jnp.tile(pred_behaviors[None], (n_preds, 1))\n", - "\n", - "\n", - "params = jnp.concatenate([prey_batch_params, pred_batch_params], axis=0)\n", - "sensed = jnp.concatenate([prey_batch_sensed, pred_batch_sensed], axis=0)\n", - "behaviors = jnp.concatenate([prey_batch_behaviors, pred_batch_behaviors], axis=0)\n", - "print(params.shape, sensed.shape, behaviors.shape)\n", - "\n", - "\n", - "prey_color = jnp.array([0., 0., 1.])\n", - "pred_color = jnp.array([1., 0., 0.])\n", - "\n", - "prey_color=jnp.tile(prey_color, (n_preys, 1))\n", - "pred_color=jnp.tile(pred_color, (n_preds, 1))\n", - "\n", - "agent_colors = jnp.concatenate([\n", - " prey_color,\n", - " pred_color\n", - "])\n", - "\n", - "agents = AgentState(\n", - " # idx in the entities (ent_idx) state to map agents information in the different data structures\n", - " ent_idx=jnp.arange(max_agents, dtype=int), \n", - " prox=jnp.zeros((max_agents, 2)),\n", - " motor=jnp.zeros((max_agents, 2)),\n", - " behavior=behaviors,\n", - " params=params,\n", - " sensed=sensed,\n", - " wheel_diameter=jnp.full((max_agents), wheel_diameter),\n", - " speed_mul=jnp.full((max_agents), speed_mul),\n", - " max_speed=jnp.full((max_agents), max_speed),\n", - " theta_mul=jnp.full((max_agents), theta_mul),\n", - " proxs_dist_max=jnp.full((max_agents), prox_dist_max),\n", - " proxs_cos_min=jnp.full((max_agents), prox_cos_min),\n", - " proximity_map_dist=jnp.zeros((max_agents, 1)),\n", - " proximity_map_theta=jnp.zeros((max_agents, 1)),\n", - " color=jnp.tile(agent_colors, (max_agents, 1))\n", - ")\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Objects" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [], - "source": [ - "\n", - "# Entities idx of objects\n", - "start_idx, stop_idx = max_agents, max_agents + max_objects \n", - "objects_ent_idx = jnp.arange(start_idx, stop_idx, dtype=int)\n", - "\n", - "res_color = jnp.array([0., 1., 0.])\n", - "pois_color = jnp.array([1., 0., 1.])\n", - "\n", - "res_color=jnp.tile(res_color, (n_preys, 1))\n", - "pois_color=jnp.tile(pois_color, (n_preds, 1))\n", - "\n", - "objects_colors = jnp.concatenate([\n", - " res_color,\n", - " pois_color\n", - "])\n", - "\n", - "objects = ObjectState(\n", - " ent_idx=objects_ent_idx,\n", - " color=jnp.tile(objects_colors, (max_objects, 1))\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### State" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [], - "source": [ - "state = State(\n", - " time=0,\n", - " box_size=box_size,\n", - " max_agents=max_agents,\n", - " max_objects=max_objects,\n", - " neighbor_radius=neighbor_radius,\n", - " collision_alpha=collision_alpha,\n", - " collision_eps=collision_eps,\n", - " dt=dt,\n", - " entities=entities,\n", - " agents=agents,\n", - " objects=objects\n", - ") " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Test the simulation" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [], - "source": [ - "from vivarium.experimental.environments.braitenberg.render import render, render_history" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiEAAAIjCAYAAADV38uMAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAABaF0lEQVR4nO3dd3wUdf7H8ddmUyEkoSYggaCA9CIIAjY0isghCKIip4CIjSLgz352EcF2BygIJyAKdin2g1BOepMggoAcTSAgJYm0lN35/TGwEgiyZTazSd7PPOaBmfLdTybCvvc73/mOwzAMAxEREZEiFmZ3ASIiIlI6KYSIiIiILRRCRERExBYKISIiImILhRARERGxhUKIiIiI2EIhRERERGyhECIiIiK2UAgRERERWyiEiIiIiC0UQkTEZz/99BO33HILNWvWJDo6mgsuuIDrrruOMWPGePZ5+eWXmTlzpt+vsWHDBp577jm2b98eeMEiEpIcenaMiPhiyZIltG/fnho1atC7d2+SkpLYtWsXy5YtY+vWrfz6668AxMbGcssttzBlyhS/Xuezzz6jR48ezJ8/n6uvvtq6H0BEQka43QWISPEyfPhw4uPjWblyJQkJCQW27d+/356iRKRY0uUYEfHJ1q1badiw4VkBBKBKlSoAOBwOjh49ynvvvYfD4cDhcNCnTx8AduzYwYMPPsjFF19MTEwMFStWpEePHgUuu0yZMoUePXoA0L59e08bCxYs8Ozz7bffcsUVV1C2bFnKlStHp06d+Pnnn4P1Y4tIEKgnRER8UrNmTZYuXcr69etp1KhRofu8//773HPPPbRq1Yp7770XgIsuugiAlStXsmTJEm6//XaqV6/O9u3bGTduHFdffTUbNmygTJkyXHnllQwePJjRo0fz5JNPUr9+fQDPn++//z69e/emQ4cOjBw5kmPHjjFu3Dguv/xyfvzxR1JSUoJ/IkQkYBoTIiI+mTNnDh07dgSgVatWXHHFFVx77bW0b9+eiIgIz37nGhNy/PhxYmJiCqxbtmwZbdq0YerUqdx5553AuceEHDlyhOTkZHr06MGECRM86/ft28fFF1/MrbfeWmC9iIQuXY4REZ9cd911LF26lJtuuon09HRGjRpFhw4duOCCC5g9e/Z5jz89gOTl5XHw4EFq165NQkICa9asOe/xc+bMITMzk549e3LgwAHP4nQ6ad26NfPnzw/o5xORoqPLMSLis0svvZQvvviC3Nxc0tPTmTFjBm+++Sa33HILa9eupUGDBuc89vjx44wYMYLJkyeze/duTu+MzcrKOu9rb9myBYBrrrmm0O1xcXE+/jQiYheFEBHxW2RkJJdeeimXXnopdevWpW/fvnz66ac8++yz5zxm0KBBTJ48mSFDhtCmTRvi4+NxOBzcfvvtuN3u877mqX3ef/99kpKSztoeHq5/1kSKC/1tFRFLtGzZEoC9e/cC5h0yhfnss8/o3bs3r7/+umfdiRMnyMzMLLDfuY4/NcC1SpUqpKamBlq2iNhIY0JExCfz58+nsPHs33zzDQAXX3wxAGXLlj0rWAA4nc6zjh8zZgwul6vAurJlywKc1UaHDh2Ii4vj5ZdfJi8v76z2f//9d69/FhGxl3pCRMQngwYN4tixY9x8883Uq1eP3NxclixZwscff0xKSgp9+/YFoEWLFsydO5c33niDatWqUatWLVq3bs3f/vY33n//feLj42nQoAFLly5l7ty5VKxYscDrNGvWDKfTyciRI8nKyiIqKoprrrmGKlWqMG7cOO68804uueQSbr/9dipXrszOnTv5+uuvadeuHWPHjrXj1IiIrwwRER98++23xt13323Uq1fPiI2NNSIjI43atWsbgwYNMvbt2+fZ75dffjGuvPJKIyYmxgCM3r17G4ZhGIcPHzb69u1rVKpUyYiNjTU6dOhg/PLLL0bNmjU9+5wyceJE48ILLzScTqcBGPPnz/dsmz9/vtGhQwcjPj7eiI6ONi666CKjT58+xqpVq4rgLIiIFTRPiIiIiNhCY0JERETEFgohIiIiYguFEBEREbGFQoiIiIjYQiFEREREbKEQIiIiIrYo8ZOVud1u9uzZQ7ly5c45DbSIiIiczTAM/vjjD6pVq0ZYmPX9FiU+hOzZs4fk5GS7yxARESm2du3aRfXq1S1vt8SHkHLlygHmCdQjvkVERLyXnZ1NcnKy573UaiU+hJy6BBMXF6cQIiIi4odgDWfQwFQRERGxhUKIiIiI2EIhRERERGxR4seEeMMwDPLz83G5XHaXUmo5nU7Cw8N1G7WISClS6kNIbm4ue/fu5dixY3aXUuqVKVOGqlWrEhkZaXcpIiJSBEp1CHG73Wzbtg2n00m1atWIjIzUJ3EbGIZBbm4uv//+O9u2baNOnTpBmRRHRERCS6kOIbm5ubjdbpKTkylTpozd5ZRqMTExREREsGPHDnJzc4mOjra7JBERCbJSHUJOCeRT944d8OGHsHs3nDgB8fHQogV06wZRURYWWQqo90NEpHRRCPHTf/4Do0fDN99AWJi5GAY4HJCXB+XLw/33w4ABcMEFdldb/OxgB7/xG8c4RgIJ1KUu8cTbXZaIiDU2AouBw0AEkAh0BBJsrMkGCiE+crng4YfhX/+C8HAzeLhc5nK6w4dh1CgYNw6+/hratrWn3uLEjZujHKUnPZnJzALbooiiF70YwAAu4RJ7ChQRCUQeMAsYA/z35DonYABuIBq4E3gQaGZDfTZQ/7cPDAMefNDsAQHIz//r/V0uyM6Ga66B5cuDX19xdoQjbGITBzhAOulnbc8hh6lMpQUtuIEbyCLLhipFRPy0H2gH9MDsATnFhRlAAE4Ak4HmwFOY4aSEUwjxwcSJMGGCGUa85XabYeXGG83ekZLG4XAwc+bMgNrIIotNbMKF2Z3k9vyNLCgfM/XNZS5tacshDgX0uiIiReIA0Ab48eT3fzUl1akPty8DAyjxQUQhxEtuN7z8sn/HulxmAJkyxdKSSoRjHGMrWzF8+JvmwsUmNnETN5FHXhCrExEJkAF0AXbwZ8Dw1jjgLcsrCikKIV6aM8e8EyYQo0ebYcYK3333HZdffjkJCQlUrFiRv/3tb2zdutWzfcmSJTRr1ozo6GhatmzJzJkzcTgcrF271rPP+vXr6dixI7GxsSQmJnLnnXdy4MABz/arr76awYMH8+ijj1KhQgWSkpJ47rnnPNtTUlIAuPnmm3E4HJ7v09PTad++PeXKlSMuLo4WLVqwatWqQn+O3ew+Z8/HX3HhYjGLzxo7IiISUuYBS/jr3o+/8jyU5M9aCiFeGj/eHIjqL8OA7dth/nxr6jl69CjDhg1j1apVpKWlERYWxs0334zb7SY7O5vOnTvTuHFj1qxZw4svvshjjz1W4PjMzEyuueYamjdvzqpVq/juu+/Yt28ft956a4H93nvvPcqWLcvy5csZNWoUL7zwAnPmzAFg5cqVAEyePJm9e/d6vu/VqxfVq1dn5cqVrF69mscff5yIiIizfoYccgIa2+HEyRjG+H28iEjQjSWwW0AOQEn+rKW7Y7y0bt35B6Kej8MBGzfCtdcGXk/37t0LfD9p0iQqV67Mhg0bWLRoEQ6Hg4kTJxIdHU2DBg3YvXs3/fv39+w/duxYmjdvzsunXWOaNGkSycnJbN68mbp16wLQpEkTnn32WQDq1KnD2LFjSUtL47rrrqNy5coAJCQkkJSU5Gln586dPPLII9SrV89zXGEOcKDQ9d5y4eIHfuBnfqYhDQNqS0TEcnuA2eBHZ++fnJh30/SwpKKQo54QL/3xR+BtOJ3m3TJW2LJlCz179uTCCy8kLi7Ocylk586dbNq0iSZNmhSYdbRVq1YFjk9PT2f+/PnExsZ6llOh4fTLOk2aNClwXNWqVdm/f/9f1jZs2DDuueceUlNTeeWVVwq0dzor7nAJI4w00gJuR0TEcj8SWAAB8zJO4VezSwSFEC9ZMau72w2xsYG3A9C5c2cOHTrExIkTWb58OctP3gOcm5vr1fFHjhyhc+fOrF27tsCyZcsWrrzySs9+Z15GcTgcuM8zsOW5557j559/plOnTsybN48GDRowY8aMs/bL93mU1tmcOHWXjIiEJqtmEjiO74NaiwldjvFS7dqwa1dgA0vdbjjZYRGQgwcPsmnTJiZOnMgVV1wBwKJFizzbL774Yj744ANycnKIOjl3/KnxGqdccsklfP7556SkpBAewGCXiIgIXGfO1AbUrVuXunXrMnToUHr27MnkyZO5+eabC+zjIPCHBRoYOHEG3I6IiOWsegSW8+RSAqknxEv9+wd+Z0ulSnDDDYHXUr58eSpWrMiECRP49ddfmTdvHsOGDfNsv+OOO3C73dx7771s3LiR77//ntdeew3A85TgAQMGcOjQIXr27MnKlSvZunUr33//PX379i00VJxLSkoKaWlpZGRkcPjwYY4fP87AgQNZsGABO3bsYPHixaxcuZL69eufdWy4BRnYhYtKVAq4HRERy1WzqJ1EsOAzW0hSCPHSzTdDxYr+H+90wgMPQGRk4LWEhYXx0UcfsXr1aho1asTQoUN59dVXPdvj4uL48ssvWbt2Lc2aNeOpp57imWeeAfCME6lWrRqLFy/G5XJx/fXX07hxY4YMGUJCQoJPD5J7/fXXmTNnDsnJyTRv3hyn08nBgwe56667qFu3LrfeeisdO3bk+eefP+vY8pQP8EyYvSmd6RxwOyIilmsFpATYhhPoG3gpocphGL7M/1n8ZGdnEx8fT1ZWFnFxcQW2nThxgm3btlGrVi2vHh3/4ovw7LO+zZgK5l0xERGwdStUr+7bsVaZNm0affv2JSsri5iYGHuKOEM++aST/udEZSfgwLYD3F/rfnZEn39SlnDC6UQnzRUiIqHrDeAR/B+g6gC2AzWsKsg3f/UeagX1hPjgiSfguuvMJ+Z66+TVDz76qGgDyNSpU1m0aBHbtm1j5syZPPbYY9x6660hE0DADBEVqOD38fnkM4ABFlYkImKxPkAk/l1OcQKdsS2AFAWFEB+Eh8MXX5jjOhyOPwPGX+3vdMK0aeblnKKUkZHB3//+d+rXr8/QoUPp0aMHEyZMKNoivHABFxDB2ROZnU8YYfSiF6mkBqEqERGLVAA+8OM4J+ZYkPHWlhNqFEJ8VLYszJoF//oXXHihue7Mm0ucTrO3pHNnWLIEevYs+jofffRRtm/f7rnk9Oabb1LGivuMLRZJJHWpSzjhXt8t48BBRzoyiUmW3GEjIhJU3YF3Md9xvXnXDQeqAvNP/lmC6RZdP4SHw6BBMHCgOQ37++/Db7/B0aPm4NWWLeGee+CCC+yutHiIIYb61Gcr5qRmhd01cypsRBDBYAYzghGW3F0jIlIk+gI1gSeB5ZjvvmfO/RGG2QNyOzAKSKLE07/iAXA44JprzEUCE0UUF3IheeRxC7cwmtEc57hnewopDGIQvekd0DgSERHbXAMsA9ZiPiF3HnAYc8xIInAHZlgpRbMOKIRISIkkkud4jpd5mWyyOcYxEkgghhhdehGRkqEZ8I7dRYQGhZAArWc905jGHvZwghPEE08LWnAHd1COcnaXV2yFEUbCyS8RESmZFEL8YGDwOZ/zT/7JYhYTTjjGya8wwvg3/2YYw+hLX4YwhNrUtrtkERGRkKO7Y3yURx796EcPerCMZYA5X4ULF27c5JOPgcExjvEO79CUpsxhjs1Vi4iIhB6FEB8YGPSlL1OYApjPLfkr+eRzghPcyI0sYEHwCzxpwYIFOBwOMjMzA9pHREQkmBRCfDCa0Uxj2p/TjHvBffLrJm7id34PYnW+adu2LXv37iU+Pt6S9hRqRETEVwohXnLhYhSj/DrWjZujHGUSkyyuyn+RkZEkJSV5nqorIiJS1BRCvPQN37CHPX4f78bNWMae9xKOt3Jychg8eDBVqlQhOjqayy+/nJUrVxbYZ/HixTRp0oTo6Gguu+wy1q9f79lWWM/FokWLuOKKK4iJiSE5OZnBgwdz9OjRAq/52GOPkZycTFRUFLVr1+bdd99l+/bttG/fHoDy5cvjcDjo06cPAJ999hmNGzcmJiaGihUrkpqaWqBNEREpvRRCvPQO7+DEGVAbv/Ebc5lrST2PPvoon3/+Oe+99x5r1qyhdu3adOjQgUOHDnn2eeSRR3j99ddZuXIllStXpnPnzuTl5RXa3tatW7nhhhvo3r0769at4+OPP2bRokUMHDjQs89dd93Fhx9+yOjRo9m4cSPvvPMOsbGxJCcn8/nnnwOwadMm9u7dy7/+9S/27t1Lz549ufvuu9m4cSMLFiygW7dulPAHN4uIiLeMEi4rK8sAjKysrLO2HT9+3NiwYYNx/Pjx87ZTy6hlEOBXmBFmjDZGB/wzHTlyxIiIiDCmTZvmWZebm2tUq1bNGDVqlDF//nwDMD766CPP9oMHDxoxMTHGxx9/bBiG4dnn8OHDhmEYRr9+/Yx77723wOv88MMPRlhYmHH8+HFj06ZNBmDMmTOn0JrObM8wDGP16tUGYGzfvt2rn8uX34eIiATfX72HWkE9IV46wpGA2wgjjD/4I+B2tm7dSl5eHu3atfOsi4iIoFWrVmzcuNGzrk2bNp7/rlChAhdffHGB7adLT09nypQpxMbGepYOHTrgdrvZtm0ba9euxel0ctVVV3ldZ9OmTbn22mtp3LgxPXr0YOLEiRw+fNiPn1hEREoihRAvlaVswG24cYfsLKpHjhzhvvvuY+3atZ4lPT2dLVu2cNFFFxETE+Nzm06nkzlz5vDtt9/SoEEDxowZw8UXX8y2bduC8BOIiEhxoxDipXrUC3hMiBs3F3FRwLVcdNFFREZGsnjxYs+6vLw8Vq5cSYMGDTzrli1b5vnvw4cPs3nzZurXr19om5dccgkbNmygdu3aZy2RkZE0btwYt9vNwoULCz0+MjISAJer4MBbh8NBu3bteP755/nxxx+JjIxkxowZfv/sIiJSciiEeOle7g34zpYkkrie6wOupWzZsjzwwAM88sgjfPfdd2zYsIH+/ftz7Ngx+vXr59nvhRdeIC0tjfXr19OnTx8qVapE165dC23zscceY8mSJQwcOJC1a9eyZcsWZs2a5RmYmpKSQu/evbn77ruZOXMm27ZtY8GCBXzyyScA1KxZE4fDwVdffcXvv//OkSNHWL58OS+//DKrVq1i586dfPHFF/z+++/nDEIiIlLKBGWkSQixamBqnpFnJBqJAQ1KfdF40bKf6/jx48agQYOMSpUqGVFRUUa7du2MFStWGIbx5yDRL7/80mjYsKERGRlptGrVykhPT/ccX9hA0hUrVhjXXXedERsba5QtW9Zo0qSJMXz48AKvOXToUKNq1apGZGSkUbt2bWPSpEme7S+88IKRlJRkOBwOo3fv3saGDRuMDh06GJUrVzaioqKMunXrGmPGjPnLn0kDU0VEQkewB6Y6DKNk3y+ZnZ1NfHw8WVlZxMXFFdh24sQJtm3bRq1atYiOjj5vWy/nvco/wh/DcPh2ysIII5potrKVJJJ8OjZYvv/+ezp27MiJEyc8l1Ls5uvvQ0REguuv3kOtoMsxXnC7Yds2SE1/mKszu+Lw4aYiB+aMpF/wRcgEkH379jFr1izq1KkTMgFERERKH4WQ83C7YcsWOHjQ7NF46X8fknqoB8B5w0g44UQRxUxm0oEORVGuV2688Ubmzp3LW2+9ZXcpIiJSioXbXUCo27ED/jhtao9II4qXtk2nbXZHPqryLzaV/RGnOxy3w4XhMAgznBgYhBvh3JJ7B09F/x8NaWjfD1CI1atX212CiE+OHYMyZeyuQkSsphDyF44fN3tAzhRGGH872Ju/HezNz2VW8m3FDzgQsYcTYcco5ypP/WMt6HSgN5XCKtCgCaBnxIn4zTBgwwZo2dLuSkTEagohcM5nmfz+Ozgc5j+C59Lw2KU0PHZpodvyXJCZCeXLW1BkKVDCx0iLn+bPhwsvtLsKEQmGUj0mJCIiAoBjx46dtc3lggMH/jqAeGP//sCOL01O/R5O/V5EAL76CmrWtLsKEQmGUt0T4nQ6SUhIYP/JpFCmTBkcDvPaydGj5qDUQP3xh3lZx6FLMudkGAbHjh1j//79JCQk4HQGNjOtFD9uN8ybB+PHw7p1kJ1tjgFJTjY/EOTlgW7kEil5SnUIAUhKMm+b3X9Gl8WxY2ZPiBX+9z8IK9V9Tt5JSEjw/D6kdDAMmDwZhg83/56Eh0N+/p/bt28397ngAhg8GJ54wtxHREqGUj1Z2elcLhd5eXme7xcsgPvvt6aGdev0Ke58IiIi1ANSyrjd8NBDMHasd/s7HHD99fD551A28OdJiogXgj1ZmT5TnOR0Ogu8CVasaN6eG6iYGAjC702k2Hv8ce8DCJg9InPmwK23wqxZ6hERKQl0keAcLrnE7AIORHg43HabNfWIlCTz5sGrr/p+nNsN334Lb79tfU0iUvQUQs7B6YSBAwMby5GfDw8+aF1NIiXF6NGB9WT885/WDBwXEXsphPyFu+82w4g/nE5o3hwuLXwKEZFS67ffYPbsggNQfWEY5rOc5s2zti4RKXoKIX+hShXzE5uvHA5zIOq771pfk0hx9+GHgd+yHh4O779vTT0iYh+FkPO4/3546SXv93c6ITra/KTXvHnw6hIprnbv9r+H8ZT8fNi1y5p6RMQ+CiFeeOop81PXqSks/uof0CZNYPFiSE0tmtpEipvjx61p5+hRa9oREfsohHjp7383P3nNmAFXXVUwiJQpA1WrwqJFsGaNekBE/kp8vDXtVKxoTTsiYh/dae+D8HDo2tVcDMP8JBYebl5++eADTc0u4o0WLcxp2APhdJrtiEjxpp4QPzkcEBtrBhCAW26BTZvsrUmkOLj5ZqhQIbA23G7o39+aekTEPgohFomOhrp17a5CJPRFRsIDD/g/ODU8HP72N6hRw9q6RKToKYRYqFEjuysQKR4efBDKlfMviBgGPPmk9TWJSNFTCLGQVQPuREq6atXg66/NXg1vg8ipMVeTJsFllwWvNhEpOgohImKLtm1h4ULzAY/nezyC02kGlo8/hrvuKpr6RCT4FEJExDatW8Ovv8KoUVCzprkuLMwMHKeCSfny8NhjsGWL+QRdESk5HIZhGHYXEUzZ2dnEx8eTlZVFXFyc3eWIyDm43ebzYDZsgOxsKFsWUlLgxhshKsru6kRKp2C/h2qeEBEJCWFh5kzDmm1YpPTQ5RgRERGxhXpCJHTkALuBLKAMUBXQFTQRkRJLPSFiv83AMKAycBFwCVAPqADcBvwXKNEjl0RESieFELHPEeAW4GJgNPDHGdtdwBfAVUBjYEuRViciIkGmECL2yAQuB2ae/N51jv3yT/75C9AK+DGoVYmISBFSCJGilwd0AdZz7vBxJhdmT8n1wK4g1SUiIkVKIUSK3qeY4zy8DSCnuDB7UF6wuiAREbGDQogUvTH4/39ePvABZhgREZFiTSFEilY6sAxwB9BGDjDVmnJERMQ+toYQl8vF008/Ta1atYiJieGiiy7ixRdf5PSZ5A3D4JlnnqFq1arExMSQmprKli26TaLY+hbw4/HtBRjAlxbUIiIitrI1hIwcOZJx48YxduxYNm7cyMiRIxk1ahRjxozx7DNq1ChGjx7N+PHjWb58OWXLlqVDhw6cOHHCxsrFbwex5v+6/Ra0ISIitrJ1xtQlS5bQpUsXOnXqBEBKSgoffvghK1asAMxekH/+85/84x//oEuXLgBMnTqVxMREZs6cye23335Wmzk5OeTk5Hi+z87OLoKfRERERHxla09I27ZtSUtLY/PmzQCkp6ezaNEiOnbsCMC2bdvIyMgg9bQnWsXHx9O6dWuWLl1aaJsjRowgPj7esyQnJwf/BxHvVSSw8SAADqCKBbWIiIitbA0hjz/+OLfffjv16tUjIiKC5s2bM2TIEHr16gVARkYGAImJiQWOS0xM9Gw70xNPPEFWVpZn2bVLk0qElBvx/dbcwtxkQRsiImIrWy/HfPLJJ0ybNo3p06fTsGFD1q5dy5AhQ6hWrRq9e/f2q82oqCiioqIsrlQs0wRoAyzH/x6RKOAuyyoSERGb2BpCHnnkEU9vCEDjxo3ZsWMHI0aMoHfv3iQlJQGwb98+qlat6jlu3759NGvWzI6SxQqDgMKvpp1fOGYAibeuHBERsYetl2OOHTtGWFjBEpxOJ263+RG5Vq1aJCUlkZaW5tmenZ3N8uXLadOmTZHWKha6BfOhdL7equvEfLLu05ZXJCIiNrC1J6Rz584MHz6cGjVq0LBhQ3788UfeeOMN7r77bgAcDgdDhgzhpZdeok6dOtSqVYunn36aatWq0bVrVztLl0BEALOA9sA6vBsjEg6UA74HqgevNBERKTq2hpAxY8bw9NNP8+CDD7J//36qVavGfffdxzPPPOPZ59FHH+Xo0aPce++9ZGZmcvnll/Pdd98RHR1tY+USsHjgB+Bu4BPMXo7Cwkg45lTt9YEvgNpFVaCIiASbwzh9etISKDs7m/j4eLKysoiLi7O7HCnMVmA8MBHIOm19ONADGAC0xbw1V0REikyw30Nt7QkRAeAi4FVgOLAXM4iUAZKAWBvrEhGRoFIIkdARCdS0uwgRESkqeoquiMjpDAOOHQN3oFP7isj5KISIiGRnw9tvQ8OGEB4OZcuaf1avDi+8AHv32l2hSImkECIipVd+Pjz+OCQlwcCBsHHjnz0ghgG7d5shJDkZevaEzExbyxUpaRRCRKR0OnECOneGUaPg+HEzdBR2s6DLZS6ffgqXXaZeERELKYSISOnjdkPv3vCf/xQePArjcsHWrXD99fDHH8GtT6SUUAgRkdJn5kz45BPfB5/m55uXbEaNCkpZIqWNQoiIlD5jxoDT14cXneRywbhxkJtrbU0ipZBCiIiULr/8AgsWmGHCXwcPwowZlpUkUlophIhI6fLFF/73gpwSFmYOVBWRgCiEiEjpsn+/GSIC4XZDRoY19YiUYgohImK7XHL5mI+5nuupTW0u4ALqU59e9OIHfsDAwuds5uVZ086+fbBzp/d314jIWfTsGBGxTR55jGAEoxnNQQ4SRhhuzDtW9rCHX/mV6UynHvV4mqe5gzsCf9Hy5a0LDuPHQ2ws1K9vLhddBBER1rQtUgoohIiILf7gD7rSlfnM9/R0nAogp+STD8AmNtGLXqSTziu8ggOH/y981VUwfLj/x4N5Oeeee+CxxwJrR6SU0+UYESlyeeTRjW4sZKFXl1pO7TOKUbzAC4G9+LXXQq1a4AggyDid0K9fYHWIiEKIiBS9N3mTNNJw4fttss/xHEtZ6v+Lh4XBoEH+Hx8eDrfdBpUq+d+GiAAKISJSxFy4GM1ovwebhhPOWMYGVkS/fmZvSLiPV6TDwiAqCp56KrDXFxFAIUREitg3fMNudvt9fD75fMIn7Ge//0XExcGcOeYgVW+DiNNp7jt7NtSr5/9ri4iHQoiIFKmpTMVJYJOFuXHzCZ8EVsiFF8KqVXDxxeb355rA7NScIuXLw8KFcM01gb2uiHgohIhIkdrJTr/GgpzOiTOg3hSPGjUgPR2+/tp8Om5hg1WbN4f33jPnBLnsssBfU8QPhmE+vDknx+5KrKVbdEWkSB3jmCXtHOe4Je3gdMKNN5rLzp3ms2WysqBsWUhJgQYNrHkdER/l5ppPGRgzBpYt+/Ohz7GxcMcd8OCD0LSpvTUGSiFERIpUecoH3IaBQQIJgRdzpho1zEXEZu+8A08+CYcOmTnZfdoUOkeOwKRJMGGC2Tk3aZI5V15xpMsxIlKkWtKS8AA//+STT3OaW1SRSOgwDHjkEbj/fjOAQOEPfM435/Fj5Upo3RqWBnDXup0UQkSkSN3P/Z6ZUP2VRBKd6GRRRSKhY+RIeO017/d3ueDoUbjhBvNKYnGjECIiRaoudbmGa/y+QyaMMAYwIODeFCkGsoBfgNXAr8AJe8sJtm3bzEswvnK7zSAyYID1NQWb/haLSJF7mqeZz3yfj3PiJJ547uXeIFQlIcEA/gu8BXwBBW6kigX6AfcDNk3V4sLFalazn/3kkUd5ynMJlxBHXMBtv/OOeUd4YZdfzluXC+bNg82boW7dgEspMuoJEZEidzVXM45xPh3jxEkkkXzHd1ShSpAqE1ttARoDVwMz4Kw7uY9ghpP6QBcgu+hK+53fGclIUkihNa3pTGe60Y32tCeRRO7nftJJ97v9EyfMEOJPADklPNx8sHNxohAiIra4j/uYwhScJ7/OxXHyK4EE/st/uZRLi7BKKTJrgVbAppPfn2vY0Kn1XwNtgUPBLQvg3/ybC7iAJ3mS3/jtrO0nOMG7vEszmnEHd3DCj+tG//0vZGYGVmd+Pnz4YWBtFDWFEBGxTW96s4lNDGUo8cQDZo9HBBGEnfznKYUUXud1trCFlrS0s1wJlt+A64E/OHf4OJMLc7zI34DcINWF+eTm/vQnjzzcuM+536nB1h/zMR3o4FUQMQw4fNi8hLJ4sTX1HiqCUGYlh2EY/j1FqpjIzs4mPj6erKws4uICv2YnIsFxnON8yZfsZCdHOUo88TSmMe1p7wkkUkLdD7yL9wHkTO8Bd1lXzikf8zG3c7vPx4URxq3cyocU3i1hGLB3L2zcaP554IA5nuPLLwOt2JxTJC+v8Ml//RHs91CFEBERsU8WkIT/d76EAc2BVZZVBJgDUFNIKfTyi7fWsMbr+Wxmz4YuXfx+KY/y5a3tDQn2e6g+XoiIiH2mAoE8D8WNeQvvamvKOeU7vgsogIQT7tPg6zZtvH+g8zlfMxyuvTawNoqaQoiIiNjnGwvacALfWtDOacYyNqCnPeeTz/u8TyaZXu1fuTLcdltgQSQ/HwYO9P94OyiEiIiIfX7HnBskEGFYfpfMAhYE/LTnE5xglQ/XiQYM+HM6dl85HOb8IFde6d/xdlEIEREROU0uuX7dZluYwxz2et/LLjPHhYT5+c782mvWDUgtKgohIiJinypAoG+cbqCiBbWcFMhlmDNFEOH1vg4HTJ8OrVr5HkRGj4bOnX0sLgQohIiIiH3+ZkEbLrDyeYanHg9ghcpU9mn/MmUgLQ1uvtn8/lxjRBwOc4mKgg8+KH5jQU5RCBEREfv8HYgO4PgwoDXQzJJqPG7n9oAfkphIIq1p7fNxZcrAZ5/BmjXQty9EF3J+UlLgjTfMeUZ69QqoTFtpnhAREbHXg8BE/J+s7H3MMGOhdNJpFkCyCSOM53iOp3k64FqysiA93ZxdNTISEhOhWTP/x474QpOVBUghREQkxO0BWmDeKePLDSlOoB0wF3wYeuG1NrRhJSv9ukvGiZNd7KIqVa0vrAhpsjIRESnZqgH/AeLB6ysgTqAJMIugBBCAiUwkmmi/HhvwT/5Z7ANIUVAIERER+zXGnHq98cnvzxVGnJh303QDfgASgldSIxrxNV8TQ4xPd8w8x3MMpJiOFC1iCiEiIhIaamFOv74UuJ2zezjigYeBX4FPgLLBL+kqrmIpS7mESwAKHax6KqAkksh7vMezPBv8wkoIjQkREZHQdBTYDxzB7PFIBCLtK+dHfuRt3uZjPuYP/gDMUHI5lzOYwXSmc8B31IQaDUwNkEKIiIhYLZdc8sijDGVwBDzbWugK9ntoyYpsIiIiRSDy5JcERmNCRERExBYKISIiImILhRARERGxhUKIiIiI2EIhRERERGyhECIiImKjEyegZE+WcW66RVdERMRCe/bApEnw88/mE3BjYyElBfr2hfr1C+67fTscPQoNG9pRqf0UQkRERCywbBm89hrMmAEOh9m74XZDWJi5vPoqXHEFPPwwdOkCa9bAihVw//12V24fhRAREZEA/fvfcN99Zthwuwtuc7v/XLdkCfzwA3TvDmXKwJQpRV5qSNGYEBERkQBMngz9+5tBIz//r/d1ucw/P/8cypUzQ0tpVsp/fBEREf/99JMZQPzx9tvwySfW1lPcKISIiIj4afRoc/yHP8LCYNQoa+spbjQmRMQuLuAbYCWQCUQD1YBbT/4pIiEtMxM++OD8l2DOxe2G1avNpUULS0srNhRCRIraAWAC8BawB4g4bZsLeBi4GRgIXF3UxYmItz78EHJyAmsjPBzefbf0hhBdjhEpSj8CDYCnMQMIQN5pi/vkMgtoDzxy8nsRCTlbt5ohIhD5+bB5szX1FEfqCREpKunA5UAO5w8Wp7p3XwOOYvaa+HndWUSC48gRa9rJyrKmneJIPSEiReEPoANmAHH5eOw4YKLlFYlIgGJjrWknIcGadoojhRCRovABsB/fA8gpw9FlGZEQU7eu/4NSTwkPh3r1rKmnOFIIEQk2AxgdYBs7gf9YUIuIWOb22yE6OrA28vPhnnusqac4UggRCbalwC+YYcRf4cDb1pQjItaIi4M+ffwfnBoWBpddBk2bWlpWsaIQIhJs6y1oIx9zYKuIhJRBg8w//ZmwzO2GRx+1tp7iRiFEJNiyAKcF7WRb0IaIWKp+fXjvPfOJub56/HG4+WbraypOFEJEgq0s1gwqLWtBGyJiuTvuMGdODQ8//6UZ58kPJE8/DS+/HPzaQp3mCRGx2v79MGMG7N1rTqeYcQkYPQJrMwxIsaI4EQmGXr2gYUN4801zJlWXyxzz4XabfxqG+d/XXw9Dh8J119ldcWhwGIY/nUjFR3Z2NvHx8WRlZREXFxdwewYGDs0aJYVZuhTGjjUfi+ly/fmRyBUG7l1A5cDanwz0CbBGEQm6gwfNSzQbNpgTkcXGQkoK3HUX1Kpld3W+sfo99EzqCTmPE5zgEz7hLd5iAxs4ylGiiaYmNbmXe+lDH8pT3u4yxU5uN/zjHzBihBk8Tk0ckJd32k5vA0/h91+5OOC2wMoUkaJRsSIMG2Z3FcWDxoScgxs3L/IiSSTRm96sYhVHOIKBwXGOs4lNPMzDVKUq93EfRzlqd8liB8Mwh8ePGGF+f86ZiyZgzlTmx+CQMOABIMavCkVEQpZCSCFyyeUWbuFZniULc1J/9xlvHsbJrxxyeJd3uYIrOMABO8oVO02YAG97M4HHHqDXyf/2IYg4gbbA8z5XJiIS8hRCzmBgcA/3MItZGF7OLuXCxTrW0YlOHOd4kCuUkOFywYsv+nDA50BvzBDixVzPYUA74Csgyo/6RERCnELIGWYzm/d5/6yej/Nx4WIVq3id14NUmYScb76B3bt9POgD4Arge8wwcsbDZE7NJ1IN83kxc4D4gKoUEQlZCiFnGMtYnH7OLOXGzVu8Rb43n3Kl+Hv77T9v+vfJMuBvwIXAKGh1BJoClwHdgFmYz4p5HIi0qlgRkdCjEHKaLWxhLnNx+f2oU8ggg6/4ysKqJGStWWNekvHbDuBJGDQT1mI+Y+YT4CasmWFVRCTE2R5Cdu/ezd///ncqVqxITEwMjRs3ZtWqVZ7thmHwzDPPULVqVWJiYkhNTWXLli1BqeVTPvW7F+QUJ04+4iOLKpKQ9scfgbfhcJgTCUjoKdlTKImEBFtDyOHDh2nXrh0RERF8++23bNiwgddff53y5f+cd2PUqFGMHj2a8ePHs3z5csqWLUuHDh04ceKE5fVkkEFYgKfEhYs97LGoIglpgT7DG8w3uiVLYNWqM+YVEdvt3Wt3BSIlnq2TlY0cOZLk5GQmT57sWVfrtOnkDMPgn//8J//4xz/o0qULAFOnTiUxMZGZM2dy++23W1pPHta8CeSQY0k7EuKSkyEzM/BPzHXqwPr15uWdOnWgQQOoUsW/x3KKdX7+GapVs7sKkRLN1p6Q2bNn07JlS3r06EGVKlVo3rw5EydO9Gzftm0bGRkZpKametbFx8fTunVrli5dWmibOTk5ZGdnF1i8lUCC3z/L6SpRyZJ2JMT16xd4G1WrmrOt9ukD994L7dtDYqICSCjYsEGXZESCzNYQ8r///Y9x48ZRp04dvv/+ex544AEGDx7Me++9B0BGRgYAiYmJBY5LTEz0bDvTiBEjiI+P9yzJycle19OOdgH3hoQRRjvaBdSGFBN33QVRAUzgERYGAwac/7GbYg+3G375xe4qrHcMmA68BDwBvAzMBIs6gkV8YusD7CIjI2nZsiVLlizxrBs8eDArV65k6dKlLFmyhHbt2rFnzx6qVq3q2efWW2/F4XDw8ccfn9VmTk4OOTl/Xg7Jzs4mOTnZq4fvuHBRk5rsxte5H/4UTji72U0VqvjdhhQjDz5ozprq610yDgdERMCOHZCUFJzaxD+5ufD55/Dcc+bvJy/PDJvJyXDPPdC3L1Qqhr2dW4BxwL+BPzAvxjsAA3PuvCqYjwe4F3OeGhGC/wA7W3tCqlatSoMGDQqsq1+/Pjt37gQg6eQ/zvv27Suwz759+zzbzhQVFUVcXFyBxVtOnAxkoN+DU8MJpwc9FEBKk5EjzTEc/swXMm2aAkgoMQx49VXzEtkdd8Cvv0JOjtkjcvw4bN4Mjz9ujhO5++7idVfTB0ADYDRmAAEzeOTx5+S9+4EXgbrAvKIuUEorW0NIu3bt2LRpU4F1mzdvpmbNmoA5SDUpKYm0tDTP9uzsbJYvX06bNm2CUtO93EtVqvp8q64DB+GE8yRPBqUuCVHlysGcOdCokXdBxOk0l0mT4JZbgl+feCc/37y89uijcOiQuc5dyKzJbrfZMzJ1KrRtC+e4LBxSJgF3YoaN83XYuYHjQAdgbpDrEsHmEDJ06FCWLVvGyy+/zK+//sr06dOZMGECAwYMAMDhcDBkyBBeeuklZs+ezU8//cRdd91FtWrV6Nq1a1BqqkAF5jCHcpTzOoiEEYYTJ1/wBY1oFJS6JIQlJsKiRfB//wfxJ+dYDzvjr9apgHLllTBvnjkQVULDqSchT5vm/TEul9kzcv311swXEyxLgP4+HuM+uXQBtltdkMgZDJt9+eWXRqNGjYyoqCijXr16xoQJEwpsd7vdxtNPP20kJiYaUVFRxrXXXmts2rTJ6/azsrIMwMjKyvKprs3GZqOWUcvAwHAaToNCvhwnv+KMOGO+Md+n9qWEOn7cMKZONYzrrzeMhg0N46KLDOPSSw1jyBDD+OUXu6uTwqSlGYYZRXxfnE7DePxxu3+Cc+tsGIbTMAz8WJyGYQwr+pIltPj7HuotWwemFoVABtXkkssMZjCGMSxm8VnbL+ZiBjOYO7mTcpSzqmQRKUpdu8LXX5uXZPyRkGBelgnkTqlg2AmkgJcPAy9cHLAXKGNFQVIcBXtgqu4N/AuRRHLbya+NJ7+yyCKWWGpSk0u5FAeaz0Gk2PrtN5g9O7D5QDIz4bPPoFcvy8qyxL8xL7gH8nijbMznGfWxoiCRsymEeKn+yS8RKUE+/9y8XTqQEBIWBtOnh14IWUtgAQQgAlgXeCki52L7A+xERGyzb59/t1efzu2GPSH4vKhDFrRhAMXoTmQpfhRCRKT0ys0NrXasFGtBGw4gxoJ2RM5BIURESq+EBGueD1OxYuBtWK0GgV9wdwPVLahF5BwUQkSk9Grb1v+7Yk5xOuGKK6ypx0p38edsqP5yAyE21EVKFg1MFZHSq317qF0btm71v0fE7TafgBxq2gH1gV/w7zbdcKAT4P0zQKWo5OebzzXKzDSfQZWYaC7FkHpCRKT0cjhg8GD/j3c6oVMnOPmoiZDiAIbi/zwh+UAAp0aCYO9eeOEFqF7dDM8tW0LTpuYzqK64Aj75JDTHJ/0FhRARKd369IGUFAj3sWPY4TBvz3322WBUZY1+wG349y/9k8A11pYjfnK54OGHzSc5P/+8eVfXmZYuhdtuMwPK3OLz4B+FEBEp3U49hDAhwfsgEhZmhpAPPzQ/jYaqMOA9oLuX+5+ae/Fh4KWgVCS+ys+HHj3gzTfNMFLYgxXB3AZw8CDccIPZK1IMKISIiFx0EaxcCRdeaH5/rrlDHA5ziYmBr76C7t6+u9soCvgI+CfmHTNw9mjAU983AKYBr4Emgw4RgwbBzJnej1lyu82lVy/473+DWpoVFEJERMC8JLN+vTkF++WXF75PrVrmJ9LffoOOHYu0vICEAQ8B24BvMZ+Q2wSoBTQHegKLgZ+AO2yqUc72008wfrzvg6YNwwwigwZZcwt6EOkBdiIihdm82QwlWVlQpgzUqAGXXWb2hIgUhQcfhIkTA7uNfPlyaNXK78P1ADsRETvUrWsuInbIzoYpUwILIOHhMHYsTJ1qWVlW0+UYERGRULNkCRw/Hlgb+fnm2KUQphAiIiISag4etKadrKyQHheiECIiIlJShfgYJoUQERGRUFOpkjXtxMeHdBDxa2BqWloaaWlp7N+/H/cZE6dMmjTJksJERERKrXbtoGxZOHrU/zbCw6FLF+tqCgKfe0Kef/55rr/+etLS0jhw4ACHDx8usIiIiEiAYmPh7rt9f5zA6fLzYeBA62oKAp/nCalatSqjRo3izjvvDFZNltI8ISIiUixt3AgNGvh3bFgYNGsGq1cHVEKw30N97gnJzc2lbdu2lhciIiIip6lfH4YO9X1Mh8Nh9qC89VZw6rKQzyHknnvuYfr06cGoRURERE736qtw++3e7x8WZgaQTz81Z/gNcT5fbDpx4gQTJkxg7ty5NGnShIiIiALb33jjDcuKExERKdWcTpg0CRYvhr17z/0kXafT3FatGkyfDldcUfS1+sHnELJu3TqaNWsGwPr16wtsc4TwbUAiIiLF0r//DR9/DHXqmFO5jxkDO3b8ud3hgOuuMweh3nDDuZ8CHYL0ADsREZFQtXcvrFhR8FZbtxv274fDhyEy0pxTJD4+KC8f0g+w++233wCoXr26JcWIiIjIaQ4fPnuuj7AwSEoyl2LO54GpbrebF154gfj4eGrWrEnNmjVJSEjgxRdfPGviMhEREfGTYZh3yJRgPveEPPXUU7z77ru88sortGvXDoBFixbx3HPPceLECYYPH255kSIiIqVOKRhn6fOYkGrVqjF+/HhuuummAutnzZrFgw8+yO7duy0tMFAaEyIiIuKfkJus7NChQ9SrV++s9fXq1ePQoUOWFCUiIiIln88hpGnTpowdO/as9WPHjqVp06aWFCUiIiIln89jQkaNGkWnTp2YO3cubdq0AWDp0qXs2rWLb775xvICRUREpGTyuSfkqquuYvPmzdx8881kZmaSmZlJt27d2LRpE1cUkxnaRERExH6arExEREQKFRKTla1bt45GjRoRFhbGunXr/nLfJk2aWFKYiIiIlGxehZBmzZqRkZFBlSpVaNasGQ6Hg8I6UBwOBy6Xy/IiRUREpOTxKoRs27aNypUre/5bREREJFBehZCaNWt6/nvHjh20bduW8PCCh+bn57NkyZIC+4qIiIici893x7Rv377QScmysrJo3769JUWJiIhIyedzCDEMA0ch89kfPHiQsmXLWlKUiIiIlHxeT1bWrVs3wBx82qdPH6KiojzbXC4X69ato23bttZXKCIiIiWS1yEkPj4eMHtCypUrR0xMjGdbZGQkl112Gf3797e+QhERESmRvA4hkydPBiAlJYX/+7//06UXERERCYhmTBUREZFChcSMqZdccglpaWmUL1+e5s2bFzow9ZQ1a9ZYVpyIiIiUXF6FkC5dungGonbt2jWY9YiIiEgpocsxIiIiUqhgv4f6PE/Irl27+O233zzfr1ixgiFDhjBhwgRLCxMREZGSzecQcscddzB//nwAMjIySE1NZcWKFTz11FO88MILlhcoIiIiJZPPIWT9+vW0atUKgE8++YTGjRuzZMkSpk2bxpQpU6yuT0REREoon0NIXl6eZ5Dq3LlzuemmmwCoV68ee/futbY6ERERKbF8DiENGzZk/Pjx/PDDD8yZM4cbbrgBgD179lCxYkXLCxQREZGSyecQMnLkSN555x2uvvpqevbsSdOmTQGYPXu25zKNiIiIyPn4dYuuy+UiOzub8uXLe9Zt376dMmXKUKVKFUsLDJRu0RUREfFPSMyYeian00l+fj6LFi0C4OKLLyYlJcXKukRERKSE8/lyzNGjR7n77rupWrUqV155JVdeeSXVqlWjX79+HDt2LBg1ioiISAnkcwgZNmwYCxcu5MsvvyQzM5PMzExmzZrFwoULefjhh4NRo4iIiJRAPo8JqVSpEp999hlXX311gfXz58/n1ltv5ffff7eyvoBpTIiIiIh/Qm7a9mPHjpGYmHjW+ipVquhyjIiIiHjN5xDSpk0bnn32WU6cOOFZd/z4cZ5//nnatGljaXEiIiJScvl8d8w///lPOnToQPXq1T1zhKSnpxMdHc33339veYEiIiJSMvk1T8ixY8eYPn06GzduBKB+/fr06tWLmJgYywsMlMaEiIiI+Cek5glZtmwZX375Jbm5uVxzzTXcc889lhckIiIipYPXIeSzzz7jtttuIyYmhoiICN544w1GjhzJ//3f/wWzPhERESmhvB6YOmLECPr3709WVhaHDx/mpZde4uWXXw5mbSIiIlKCeT0mJDY2lrVr11K7dm0AcnNzKVu2LLt37w6558WcTmNCRERE/BMy84QcO3asQAGRkZFER0dz5MgRy4sSERGRks+ngan//ve/iY2N9Xyfn5/PlClTqFSpkmfd4MGDratORERESiyvL8ekpKTgcDj+ujGHg//973+WFGYVXY4RERHxT8jcort9+3bLX1xERERKL5+nbRcRERGxgkKIiIiI2EIhRERERGzhdQjZs2dPMOsQERGRUsbrENKwYUOmT58ezFpERESkFPE6hAwfPpz77ruPHj16cOjQoWDWJCIiIqWA1yHkwQcfZN26dRw8eJAGDRrw5ZdfBrMuERERKeF8mjG1Vq1azJs3j7Fjx9KtWzfq169PeHjBJtasWWNpgSIiIlIy+Xx3zI4dO/jiiy8oX748Xbp0OWvx1yuvvILD4WDIkCGedSdOnGDAgAFUrFiR2NhYunfvzr59+/x+DREREQkdPvWETJw4kYcffpjU1FR+/vlnKleubEkRK1eu5J133qFJkyYF1g8dOpSvv/6aTz/9lPj4eAYOHEi3bt1YvHixJa8rIiIi9vE6hNxwww2sWLGCsWPHctddd1lWwJEjR+jVqxcTJ07kpZde8qzPysri3XffZfr06VxzzTUATJ48mfr167Ns2TIuu+wyy2oQERGRouf15RiXy8W6dessDSAAAwYMoFOnTqSmphZYv3r1avLy8gqsr1evHjVq1GDp0qXnbC8nJ4fs7OwCi4iIiIQer3tC5syZY/mLf/TRR6xZs4aVK1eetS0jI4PIyEgSEhIKrE9MTCQjI+OcbY4YMYLnn3/e6lJFRETEYrZN275r1y4eeughpk2bRnR0tGXtPvHEE2RlZXmWXbt2Wda2iIiIWMe2ELJ69Wr279/PJZdcQnh4OOHh4SxcuJDRo0cTHh5OYmIiubm5ZGZmFjhu3759JCUlnbPdqKgo4uLiCiwiIiISeny6O8ZK1157LT/99FOBdX379qVevXo89thjJCcnExERQVpaGt27dwdg06ZN7Ny5kzZt2thRsoiIiFjIthBSrlw5GjVqVGBd2bJlqVixomd9v379GDZsGBUqVCAuLo5BgwbRpk0b3RkjIiJSAtgWQrzx5ptvEhYWRvfu3cnJyaFDhw68/fbbdpclIiIiFnAYhmHYXUQwZWdnEx8fT1ZWlsaHiIiI+CDY76G2DUwVERGR0k0hRERERGyhECIiIiK2UAgRERERWyiEiIiIiC0UQkRERMQWCiEiIiJiC4UQERERsYVCiIiIiNhCIURERERsoRAiIiIitlAIEREREVsohIiIiIgtFEJERETEFgohIiIiYguFEBEREbGFQoiIiIjYQiFEREREbKEQIiIiIrZQCBERERFbKISIiIiILRRCRERExBYKISIiImILhRARERGxhUKIiIiI2EIhRERERGyhECIiIiK2UAgRERERWyiEiIiIiC0UQkRERMQWCiEiIiJiC4UQERERsYVCiIiIiNhCIURERERsoRAiIiIitlAIEREREVsohIiIiIgtFEJERETEFgohIiIiYguFEBEREbGFQoiIiIjYQiFEREREbKEQIiIiIrZQCBERERFbKISIiIiILRRCRERExBYKISIiImILhRARERGxhUKIiIiI2EIhRERERGyhECIiIiK2UAgRERERWyiEiIiIiC0UQkRERMQWCiEiIiJiC4UQERERsYVCiIiIiNhCIURERERsoRAiIiIitlAIEREREVsohIiIiIgtFEJERETEFgohIiIiYguFEBEREbGFQoiIiIjYQiFEREREbKEQIiIiIrYIt7sAESn5drGLdNLJIotooqlOdS7lUsL0OUikVFMIEZGgcOPmP/yHsYzlG77BwCiw/UIuZBCD6E1vylPepipFxE76GCIiltvHPlrRio505Du+OyuAAGxjG8MYRnWqM5vZNlQpInZTCBERS+1lL61oRTrpALhwFbqfcfLrOMfpSlemMa0oyxSREKAQIiKWySGHG7iBPewhn3yvjjkVRvrQh0UsCnKFIhJKFEJExDKf8inrWOd1ADmdgcE/+EcQqhKRUKUQIiKWGcMYv+94ceFiIQvZyEaLqxKRUKUQIiKWWMtaVrACN26/2wgnnPGMt7AqEQllCiEiYolFLMKBI6A28slnHvMsqkhEQp1CiIhY4jCHceK0pB0RKR0UQkTEEhFEhFQ7IhL6FEJExBKJJPp1V8zpHDioSlWLKhKRUGdrCBkxYgSXXnop5cqVo0qVKnTt2pVNmzYV2OfEiRMMGDCAihUrEhsbS/fu3dm3b59NFYvIuXSmsyW9GD3paUE1IlIc2BpCFi5cyIABA1i2bBlz5swhLy+P66+/nqNHj3r2GTp0KF9++SWffvopCxcu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iIjIXyjxPSEiIiISmhRCRERExBYKISIiImILhRARERGxRYkOIW+99RYpKSlER0fTunVrVqxYYXdJJcaIESO49NJLKVeuHFWqVKFr165s2rSpwD4nTpxgwIABVKxYkdjYWLp3786+fftsqrjkeeWVV3A4HAwZMsSzTufcert37+bvf/87FStWJCYmhsaNG7Nq1SrPdsMweOaZZ6hatSoxMTGkpqayZcsWGysu3lwuF08//TS1atUiJiaGiy66iBdffLHAs0t0zgPz3//+l86dO1OtWjUcDgczZ84ssN2b83vo0CF69epFXFwcCQkJ9OvXjyNHjvhejFFCffTRR0ZkZKQxadIk4+effzb69+9vJCQkGPv27bO7tBKhQ4cOxuTJk43169cba9euNW688UajRo0axpEjRzz73H///UZycrKRlpZmrFq1yrjsssuMtm3b2lh1ybFixQojJSXFaNKkifHQQw951uucW+vQoUNGzZo1jT59+hjLly83/ve//xnff/+98euvv3r2eeWVV4z4+Hhj5syZRnp6unHTTTcZtWrVMo4fP25j5cXX8OHDjYoVKxpfffWVsW3bNuPTTz81YmNjjX/961+efXTOA/PNN98YTz31lPHFF18YgDFjxowC2705vzfccIPRtGlTY9myZcYPP/xg1K5d2+jZs6fPtZTYENKqVStjwIABnu9dLpdRrVo1Y8SIETZWVXLt37/fAIyFCxcahmEYmZmZRkREhPHpp5969tm4caMBGEuXLrWrzBLhjz/+MOrUqWPMmTPHuOqqqzwhROfceo899phx+eWXn3O72+02kpKSjFdffdWzLjMz04iKijI+/PDDoiixxOnUqZNx9913F1jXrVs3o1evXoZh6Jxb7cwQ4s353bBhgwEYK1eu9Ozz7bffGg6Hw9i9e7dPr18iL8fk5uayevVqUlNTPevCwsJITU1l6dKlNlZWcmVlZQF/PjBw9erV5OXlFfgd1KtXjxo1auh3EKABAwbQqVOnAucWdM6DYfbs2bRs2ZIePXpQpUoVmjdvzsSJEz3bt23bRkZGRoFzHh8fT+vWrXXO/dS2bVvS0tLYvHkzAOnp6SxatIiOHTsCOufB5s35Xbp0KQkJCbRs2dKzT2pqKmFhYSxfvtyn1yuRD7A7cOAALpeLxMTEAusTExP55ZdfbKqq5HK73QwZMoR27drRqFEjADIyMoiMjCQhIaHAvomJiWRkZNhQZcnw0UcfsWbNGlauXHnWNp1z6/3vf/9j3LhxDBs2jCeffJKVK1cyePBgIiMj6d27t+e8FvZvjc65fx5//HGys7OpV68eTqcTl8vF8OHD6dWrF4DOeZB5c34zMjKoUqVKge3h4eFUqFDB599BiQwhUrQGDBjA+vXrWbRokd2llGi7du3ioYceYs6cOURHR9tdTqngdrtp2bIlL7/8MgDNmzdn/fr1jB8/nt69e9tcXcn0ySefMG3aNKZPn07Dhg1Zu3YtQ4YMoVq1ajrnJVCJvBxTqVIlnE7nWXcF7Nu3j6SkJJuqKpkGDhzIV199xfz586levbpnfVJSErm5uWRmZhbYX78D/61evZr9+/dzySWXEB4eTnh4OAsXLmT06NGEh4eTmJioc26xqlWr0qBBgwLr6tevz86dOwE851X/1ljnkUce4fHHH+f222+ncePG3HnnnQwdOpQRI0YAOufB5s35TUpKYv/+/QW25+fnc+jQIZ9/ByUyhERGRtKiRQvS0tI869xuN2lpabRp08bGykoOwzAYOHAgM2bMYN68edSqVavA9hYtWhAREVHgd7Bp0yZ27typ34Gfrr32Wn766SfWrl3rWVq2bEmvXr08/61zbq127dqddev55s2bqVmzJgC1atUiKSmpwDnPzs5m+fLlOud+OnbsGGFhBd+anE4nbrcb0DkPNm/Ob5s2bcjMzGT16tWefebNm4fb7aZ169a+vWBAw2pD2EcffWRERUUZU6ZMMTZs2GDce++9RkJCgpGRkWF3aSXCAw88YMTHxxsLFiww9u7d61mOHTvm2ef+++83atSoYcybN89YtWqV0aZNG6NNmzY2Vl3ynH53jGHonFttxYoVRnh4uDF8+HBjy5YtxrRp04wyZcoYH3zwgWefV155xUhISDBmzZplrFu3zujSpYtuFw1A7969jQsuuMBzi+4XX3xhVKpUyXj00Uc9++icB+aPP/4wfvzxR+PHH380AOONN94wfvzxR2PHjh2GYXh3fm+44QajefPmxvLly41FixYZderU0S26ZxozZoxRo0YNIzIy0mjVqpWxbNkyu0sqMYBCl8mTJ3v2OX78uPHggw8a5cuXN8qUKWPcfPPNxt69e+0rugQ6M4TonFvvyy+/NBo1amRERUUZ9erVMyZMmFBgu9vt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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "render(state)" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [], - "source": [ - "env = SelectiveSensorsEnv(state)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Autonomous behaviors" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [], - "source": [ - "n_steps = 10_000\n", - "hist = []\n", - "\n", - "for i in range(n_steps):\n", - " state = env.step(state)\n", - " hist.append(state)" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAikAAAIjCAYAAADGCIt4AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAABh4ElEQVR4nO3dd3wU1f7G8c9mUyEkgQAJkSAgIEV6k6pIrqDoBUURRSlSVIpSbFwURUUQuyCgKGAB6xVQfioXQ1GKVOlIURDEhJ6EFkJ25/fHmJVQk+xsdpI8b1770p1y8t0lZJ+cc+aMwzAMAxERERGbCfB3ASIiIiIXopAiIiIitqSQIiIiIrakkCIiIiK2pJAiIiIitqSQIiIiIrakkCIiIiK2pJAiIiIitqSQIiIiIrakkCJSiPTs2ZOKFSv6uwwREUsopIjYnMPhyNFj0aJF/i71siZOnMj06dP9XcYFzZ8/n5YtW1KsWDFKlizJHXfcwe7du8877vjx4wwePJjy5csTEhJCjRo1mDRp0nnHTZ8+/aJ/V8nJyecd//XXX9OgQQNCQ0OpUKECzzzzDJmZmb54qSIFRqC/CxCRS/voo4+yPf/www+ZP3/+edtr1KjBlClTcLvd+VlerkycOJHSpUvTs2dPf5eSzdy5c+nYsSMNGjRg7NixpKWl8eabb9KyZUt++eUXypQpA4DL5aJdu3asXr2aAQMGULVqVebNm0f//v05evQo//nPf85r+7nnnqNSpUrZtkVFRWV7/t1339GpUyeuv/56xo8fz8aNG3nhhRc4cODABQOQSJFhiEiBMmDAAKOg/tOtVauWcd111/m7jPPUrFnTqFKlinH69GnPtnXr1hkBAQHG0KFDPds+//xzAzDef//9bOd37tzZCA0NNfbv3+/ZNm3aNAMwVq1alaOvX7duXePMmTOebSNGjDAcDoexdetWb16aSIGm4R6RQuTcOSm7d+/G4XDwyiuv8Pbbb1O5cmWKFSvGjTfeyN69ezEMg+eff57y5csTFhZGx44dOXLkyHntfvfdd7Rq1YrixYtTokQJOnTowObNm7Mdk5ycTK9evTzDIOXKlaNjx46eIZOKFSuyefNmFi9e7Bn2uP766z3np6SkMHjwYOLj4wkJCaFKlSq89NJL2XqGzn49r7/+OldeeSVhYWFcd911bNq0KVs9Z86c4ddffyUpKemS79mRI0fYsmULt912G8HBwZ7tdevWpUaNGnz66aeebT/99BMAXbt2zdZG165dSU9PZ86cORf8GseOHcPlcl1w35YtW9iyZQv9+vUjMPCfzu3+/ftjGAZffvnlJesXKcw03CNSBMyYMYOMjAwGDRrEkSNHGDduHF26dOGGG25g0aJFPPHEE+zcuZPx48fz6KOPMnXqVM+5H330ET169KBdu3a89NJLnDx5kkmTJnmGQrJCUefOndm8eTODBg2iYsWKHDhwgPnz57Nnzx4qVqzIG2+8waBBgwgPD2fEiBEAxMTEAHDy5Emuu+469u3bxwMPPECFChVYtmwZw4cPJykpiTfeeCPb6/nwww85duwYAwYMID09nTfffJMbbriBjRs3etrct28fNWrUoEePHpecB3P69GkAwsLCzttXrFgxNm/eTHJyMrGxsZw+fRqn05ktzGQdB7BmzRr69u2bbV+bNm04fvw4wcHBtGvXjldffZWqVat69v/yyy8ANGrUKNt5cXFxlC9f3rNfpEjyd1eOiOTOpYZ7evToYVx55ZWe57t27TIAo0yZMkZKSopn+/Dhww3gvCGGu+++2wgODjbS09MNwzCMY8eOGVFRUUbfvn2zfZ3k5GQjMjLSs/3o0aMGYLz88suXrP1iwz3PP/+8Ubx4cWP79u3Ztj/55JOG0+k09uzZk+31hIWFGX/++afnuBUrVhiAMWTIkPNee48ePS5Zk8vlMqKiooy2bdtm237o0CGjePHiBmCsXr3aMAzDePXVVw3A+Omnn86rEzBuueUWz7bPPvvM6Nmzp/HBBx8Ys2bNMp566imjWLFiRunSpT2vxzAM4+WXXzaAbNuyNG7c2Lj22msvWb9IYabhHpEi4M477yQyMtLzvGnTpgDce++92YYYmjZtSkZGBvv27QPMK15SUlK4++67OXTokOfhdDpp2rQpCxcuBMxeiODgYBYtWsTRo0dzXd8XX3xBq1atKFmyZLavk5CQgMvl4scff8x2fKdOnbjiiis8z5s0aULTpk359ttvPdsqVqyIYRiXvZooICCABx54gMTERIYPH86OHTtYs2YNXbp0ISMjA4BTp04BcM899xAZGcn999/P/Pnz2b17N++++y4TJ07MdhxAly5dmDZtGt27d6dTp048//zzzJs3j8OHDzN69GjPcVnnhISEnFdbaGhotjZFihoN94gUARUqVMj2PCuwxMfHX3B7VtDYsWMHADfccMMF242IiADMD9iXXnqJYcOGERMTw7XXXsstt9xC9+7diY2NvWx9O3bsYMOGDZ6raM514MCBbM/PHi7JUq1aNT7//PPLfq0Lee655zh06BDjxo1j7NixANx444307t2byZMnEx4eDkBsbCxff/019913HzfeeCNgvgfjx4+nR48enuMupmXLljRt2pQffvjBsy1rmClr2Ols6enpFxyGEikqFFJEigCn05mr7YZhAHgmrX700UcXDBtn98IMHjyYW2+9ldmzZzNv3jyefvppxowZw4IFC6hfv/4l63O73fzrX//i8ccfv+D+atWqXfJ8bwUHB/Pee+8xevRotm/fTkxMDNWqVeOee+4hICCAKlWqeI5t3bo1v//+Oxs3buTEiRPUrVuXv/76K8d1xsfHs23bNs/zcuXKAZCUlHReaExKSqJJkyZWvESRAkkhRUQu6qqrrgKgbNmyJCQk5Oj4YcOGMWzYMHbs2EG9evV49dVX+fjjjwFzYbqLnXf8+PEcfQ34p4fnbNu3b/d6td2YmBjPxFuXy8WiRYto2rTpeT0kTqeTevXqeZ5n9YzkpP7ff/89W49RVjurV6/OFkj++usv/vzzT/r165fXlyNS4GlOiohcVLt27YiIiODFF1/kzJkz5+0/ePAgYF6dk56enm3fVVddRYkSJbINYxQvXpyUlJTz2unSpQvLly9n3rx55+1LSUk5b+XV2bNne+bNAKxcuZIVK1Zw0003ebbl9BLki3nllVdISkpi2LBhlzzu4MGDvPTSS9SpUydbSMl6b8727bffsmbNGtq3b+/ZVqtWLapXr867776b7TLlSZMm4XA4uOOOO/JUv0hhoJ4UEbmoiIgIJk2axH333UeDBg3o2rUrZcqUYc+ePfzf//0fLVq0YMKECWzfvp22bdvSpUsXatasSWBgILNmzWL//v3Z1hRp2LAhkyZN4oUXXqBKlSqULVuWG264gccee4yvv/6aW265hZ49e9KwYUNOnDjBxo0b+fLLL9m9ezelS5f2tFOlShVatmzJQw89xOnTp3njjTeIjo7ONlyU00uQAT7++GP++9//0rp1a8LDw/nhhx/4/PPP6dOnD507d8527HXXXUezZs2oUqUKycnJvPvuuxw/fpy5c+cSEPDP733Nmzenfv36NGrUiMjISNauXcvUqVOJj48/b2Xal19+mX//+9/ceOONdO3alU2bNjFhwgT69OlDjRo18vJXJ1I4+PvyIhHJnbxcgnzupcELFy40AOOLL77Itv1iq6QuXLjQaNeunREZGWmEhoYaV111ldGzZ0/PpbmHDh0yBgwYYFSvXt0oXry4ERkZaTRt2tT4/PPPs7WTnJxsdOjQwShRooQBZLsc+dixY8bw4cONKlWqGMHBwUbp0qWN5s2bG6+88oqRkZFx3ut59dVXjfj4eCMkJMRo1aqVsX79+mxfK6eXIBuGeQlz69atjZIlSxqhoaFG3bp1jcmTJxtut/u8Y4cMGWJUrlzZCAkJMcqUKWPcc889xm+//XbecSNGjDDq1atnREZGGkFBQUaFChWMhx56yEhOTr5gDbNmzTLq1atnhISEGOXLlzeeeuopz+sWKaochvH3DDkREZvbvXs3lSpV4uWXX+bRRx/1dzki4mOakyIiIiK2pJAiIiIitqSQIiIiIrbk15Dy448/cuuttxIXF4fD4WD27NnZ9huGwciRIylXrhxhYWEkJCSctz7CkSNH6NatGxEREURFRdG7d2+OHz+ej69CRPJL1lL3mo8iUjT4NaRkrdb49ttvX3D/uHHjeOutt5g8eTIrVqygePHitGvXLtt6DN26dWPz5s3Mnz+fuXPn8uOPP2rxIxERkULANlf3OBwOZs2aRadOnQCzFyUuLo5hw4Z5fmtKTU0lJiaG6dOn07VrV7Zu3UrNmjVZtWqV5zbn33//PTfffDN//vkncXFx/no5IiIi4iXbLua2a9cukpOTs63gGBkZSdOmTVm+fDldu3Zl+fLlREVFeQIKmMtSBwQEsGLFCm677bYLtn369Olsq2C63W6OHDlCdHT0RZftFhERkfMZhsGxY8eIi4vLtqChFWwbUpKTkwE899HIEhMT49mXnJxM2bJls+0PDAykVKlSnmMuZMyYMYwaNcriikVERIquvXv3Ur58eUvbtG1I8aXhw4czdOhQz/PU1FQqVKjA3r17PbeeFx/6+GNo3RoqVDCfHz4MH31kPv76C9LTITwc6tSBvn2hQwcICvJvzSIickFpaWnEx8dTokQJy9u2bUjJui38/v37Pbcyz3qeddfQ2NhYDhw4kO28zMxMjhw5csHbymcJCQkhJCTkvO0REREKKfmhXz/o1QuGDYM334QZM8DlArf7n2PS0mD5cliyBMqUgaeegkGDQMNxIlJYGYAbcPq7kLzxxXQJ266TUqlSJWJjY0lMTPRsS0tLY8WKFTRr1gyAZs2akZKSwpo1azzHLFiwALfbTdOmTfO9ZsmhwEB45BG49lqz9+TMmewBJUvWHWEPHjSP79fvwseJiBRU+4BngXggGLProBjQApgJnL7omUWCX3tSjh8/zs6dOz3Pd+3axbp16yhVqhQVKlRg8ODBvPDCC1StWpVKlSrx9NNPExcX57kCqEaNGrRv356+ffsyefJkzpw5w8CBA+natauu7LGztDTo2fPi4eRi3nsPIiPhlVd8VpqISL44CDwEzPr7+dk/Ck8BPwPLgIHACGAoUBQ7kv13b8N/7sR67iPrrqVut9t4+umnjZiYGCMkJMRo27atsW3btmxtHD582Lj77ruN8PBwIyIiwujVq5dx7NixXNWRmppqAEZqaqpVL00uZdgww3A6DQPy9vjpJ3+/AhGRvPvdMIwrDcNwGoZBDh+9DMNw+aHWHPDlZ6ht1knxp7S0NCIjI0lNTdWcFF87eRLKlTN7U/IiMBDuuAM++cTaukRE8sNhoAmwB8jM5blDgNcsr8hrvvwMte2cFCmkPvss7wEFIDMTvvwS9u+3riYRkfzyNPAHuQ8oAK9jDgMVIQopkr8++QS8XezH5YJZsy5/nIiInaQB0wFXHs8PBC58F5lCSyFF8te+fd5foRMYqJ4UESl4PgLSL3vUxWUCnwKHrCmnIFBIkfx12qLr6axqR0Qkv1gxlS4TmGNBOwWEQorkr1KlvG/D7YaoKO/bERHJT0mY17B6IxA4cNmjCg3brjgrhVSrVrB27T8LteWFywXNm1tXk4gUeseOwe+/Q2oqFCsG8fFwzq3hfO+MBW04gAwL2ikg1JMi+evBB70LKA4H1KgBLVpYV5OIFFq//AJ9+ph316hXD667Dho3NldCuOkm+L//8+5HUq6UtKANl0XtFBAKKZK/qlaFhARwenFziocf1j18ROSSjh6FG2+EBg3ggw/On8ZmGDB/Ptxyi/ljaePGfCiqDd6PX7iBlhbUUkAopEj+GzUqbyEjMBAqV4Z777W+JhEpNA4eNG8NtmCB+TzzImuSZPWg7NkDzZrBz75eg+Qh8rY+SpYAoDHQwJpyCgKFFMl/zZvD9OlmUMlpWAkMhJIlzV99wsN9Wp6IFFynT0OHDub8k5wO47hckJ4ON99snuczVwPXk/e7HLuBQZZVUyAopIh/dOtmLsgWGnrpxd2yhoWuugpWrYJKlfKnPhGxvTMXmIg6c6b5o+JivScX43KZk2uff96a2i5qNHm7UWAgcA1wp7Xl2J1CivhPx45mP+vYsVChwoWPadnSXAZ/40a48sr8rU9EbM3thpUr4f33Yfx48//ffDPvi1pnZpoh5/Bha+vMpjnwIWZQyWlYCQTKAfOAUB/VZVO6wSC6waAtuN2wdCns3WvehDAyEurUgauv9ndlIlIA7NwJL7xgTpL1RkAAjBsHw4ZZU9dFzQXuAk79/fxCn8SBmHNY6gPfArE+rimPfPkZqnVSxB4CAsw1VERE8qBKFfMqHafTu0uK3W747rt8CCm3APuAD4C3gHPnwjiAdsBA4EaK7LiHQoqIiBQKR46Yv+94u+7JwYPW1HNZUcAjwMPASszQcgqIBGoDGuFWSBERkcLB2xusZ/FmGac8cQBN8/lrFhBFtANJREQKm9Klvb/JusPhh+Xy5aIUUkREpFC49VZrlrjv1Mn7NsQaCikiIlIo1Kxpzr/3ZrgmLMxcxknsQSFFREQKjUGD8t6b4nRCr15a1NpOFFJERKTQuP128+7Gue1NcTrNOyM//bRv6pK8UUgREZFCw+mEzz+Hpk1zfrVPYKA56Xb+fE2atRuFFBERKVTCwyEx0Ry6cTov3qsS+PciHNdeC6tXQ/Xq+Vej5IxCioiIFDqhofDee+btwUaOhLJls+8PC4PevWHdOvjpJyhf3i9lymXo3j3o3j0iIoWd2w0pKeajeHEoVQqCgvxdVeGge/eIiIh4ISDADCalSvm7EskNDfeIiIiILSmkiIiIiC0ppIiIiIgtKaSIiIiILSmkiIiIiC0ppIiIiIgtKaSIiIiILSmkiIiIiC0ppIiIiIgtKaSIiIiILSmkiIiIiC0ppIiIiIgtKaSIiIiILSmkiIiIiC0ppIiIiIgtKaSIiIiILSmkiIiIiC0ppIiIiIgtKaSIiIiILSmkiIiIiC0ppIiIiIgtKaSIiIiILSmkiIiIiC0ppIiIiIgtKaSIiIiILSmkiIiIiC0ppIiIiIgtKaSIiIiILSmkiIiIiC0ppIiIiIgtKaSIiIiILSmkiIiIiC0ppIiIiIgtKaSIiIiILSmkiIiIiC0ppIiIiIgtKaSIiIiILSmkiIiIiC0ppIiIiIgtKaSIiIiILSmkiIiIiC0ppIiIiIgtKaSIiIiILSmkiIiIiC0ppIiIiIgtKaSIiIiILSmkiIiIiC0ppIiIiIgtBfq7AJEcOwx8BvwBnAQigdpAJyDEf2WJiIhvKKSI/a0GxgOfAJlk/649A5QEHgQeAuLzvToREfERDfeIfRnAK0BjYCZmIDH+/m/WA+AoMA6oCSzI/zJFRMQ3FFLEvsYAj/39/5mXOdaFOQTUDljoy6JERCS/KKSIPc0FRuTyHPffj38D+yyvSERE8plCitjTi+Ttu9MNnAImW1uOiIjkP4UUsZ8NwHLMwJEXLmASkGFZRSIi4ge2Dikul4unn36aSpUqERYWxlVXXcXzzz+PYRieYwzDYOTIkZQrV46wsDASEhLYsWOHH6sWr72L99edHQbmWFCLiIj4ja1DyksvvcSkSZOYMGECW7du5aWXXmLcuHGMHz/ec8y4ceN46623mDx5MitWrKB48eK0a9eO9PR0P1YuXlnP5SfKXk4QsMmCWkRExG9svU7KsmXL6NixIx06dACgYsWKfPLJJ6xcuRIwe1HeeOMNnnrqKTp27AjAhx9+SExMDLNnz6Zr165+q128cNSidlItakdERPzC1j0pzZs3JzExke3btwOwfv16lixZwk033QTArl27SE5OJiEhwXNOZGQkTZs2Zfny5Rdt9/Tp06SlpWV7iI2EW9ROcYvaERERv7B1T8qTTz5JWloa1atXx+l04nK5GD16NN26dQMgOTkZgJiYmGznxcTEePZdyJgxYxg1apTvChfvVAbW4N2QTyZwpTXliIiIf9i6J+Xzzz9nxowZzJw5k7Vr1/LBBx/wyiuv8MEHH3jV7vDhw0lNTfU89u7da1HFYoleeD8nJRjoYkEtIiLiN7buSXnsscd48sknPXNLateuzR9//MGYMWPo0aMHsbGxAOzfv59y5cp5ztu/fz/16tW7aLshISGEhOiOdLbVFqgE7MZcBj+3AoF7gSjrShIRkfxn656UkydPEhCQvUSn04nbbS6gUalSJWJjY0lMTPTsT0tLY8WKFTRr1ixfaxULBQBDyVtAAXOdlIHWlSMiIv5h656UW2+9ldGjR1OhQgVq1arFL7/8wmuvvcb9998PgMPhYPDgwbzwwgtUrVqVSpUq8fTTTxMXF0enTp38W7x4pz/mPXhmk/tF3d4C6llcj4iI5Dtbh5Tx48fz9NNP079/fw4cOEBcXBwPPPAAI0eO9Bzz+OOPc+LECfr160dKSgotW7bk+++/JzQ01I+Vi9cCgBnAfcCXgINL96w4MXtQXka9KCIihYTDOHv51iIqLS2NyMhIUlNTiYiI8Hc5cjY35n14XgN+w4zVZ0+qzXreGvgP5l2QRUQk3/jyM9TWPSkiBGAO/TwELACmA7uAY0BJoC7wAFDTT/WJiIjPKKRIweDAvOqnrb8LERGR/GLrq3tERESk6FJIEREREVtSSBERERFbUkgRERERW1JIEREREVvS1T0iYlsnOMFMZvIVX5FMMm7clKY0/+Jf9KY3ZSjj7xJFxIe0mBtazE3Ebg5xiOd5nqlM5TjHceDAOGvJ4YC//9zFXYxkJNWo5sdqRYo2X36GarhHRGxlJztpTGPe5m2OcxwgW0ABcOMmk0w+4zMa05if+MkfpYqIjymkiBQhhznMq7xKfeoTSyylKEVlKtOLXqxilb/LI4kkruM69rIXF67LHp9JJsc5TjvasZa1+VChiOQnhRSRIuAgB+lFL+KI43EeZx3r2M9+jnKUXeziYz6mCU2oT32+53u/1dmd7hzgQI4CShY3bjLI4N/8mzOc8WF1IpLfFFJECrnf+I3GNOZjPiaDDNy4zzsm8++7Nm5gAzdzMxOZmN9l8iu/8gM/eGrJDRcu9rGPr/naB5WJiL8opIgUYgc4wA3cwJ/8maMPfzduDAwGMICP+TgfKvzHZCbjxJnn8504Gc94CysSEX9TSBEpxB7mYf7ir1wNn2S5n/tJJtkHVZ3PwGAqU/NUZxYXLhazmD3ssbAyEfEnhRSRQiqJJL7kyzwNn4D5of8+71tc1YWlkcYxjlnS1l72WtKOiPifQopIIfUe75136W5uuHHzNm/nOeTkxklOWtbWCU5Y1paI+JdCikghNZ3pF5wkmxtJJOXLGiSRRNqyLRHxL4UUkULKqvkkf/GXJe1cShhhVKCC1+0EEkhVqlpQkYjYgUKKSCGVQYYl7aSTbkk7l+LAwUAGEuDFj6RAAulKV0pRysLKRMSfFFJECqkSlLCknSiiLGnncnrRy6tLkDPJZAADLKxIRPxNIUWkkGpMY68+9MHs4WhAA4squrTSlKYf/fLUm+LESSta0ZSmPqhMRPxFIUWkkBrIQK/WHXHipB3tqEQlC6u6tNd4jda0zlVQCSSQClTgK77CgcOH1YlIflNIESmkbuZm4ojL8/kuXAxkoIUVXV4wwXzLt9zKrQCX7AnKCjK1qMUyllGa0vlSo4jkH4UUkULKiZPneC7P5zagAe1pb3FVlxdGGF/9/ec6rvPUE/T3n6zgUotavMd7LGc5scTme50i4nsOwzDyvtpTIZGWlkZkZCSpqalERET4uxwRSz3O47zMyzk+PpBA4ohjJSuJIcaHleXMdrYzhzkc4hCZZFKKUrSlLU1pquGdwsYAfgYmAkuAVCAEuALo/vcjyl/FycX48jNUIQWFFCncDAxe5EWe4ikCCbzoCrJOnLhwUY96fMd36p2Q/DUHeArYBARCtm/TrCwaghlUXkJhxUZ8+Rmq4R6RQs6BgxGMYDObeZAHKUYxwJzTcfacj+Y053M+ZyUrFVAkf70CdAI2//383Bxt/P1IB94HmoJu0VQ0qCcF9aRI0XKMY3zHd+xnPxlkEEUUzWhGTWr6uzQpit4BHszlOYFAJWAFUNLyiiSXfPkZGmhpayJieyUoQRe6+LsMEdgF9M/DeZnA78CjkE836hY/0XCPiIj4xzuQ57nPLuBj4Kh15Yj9KKSIiEj+S8cMKXlfbxDOANMtqUZsSsM9IgXdSeAbYM/f/x8J1AGuR7+GiH3NB1IsaGc6MMSCdsSWFFJECqqdwCTgPSANcGKGEhfgBioDg4Ce6HJNsZ+/LGjDsKgdsS39niVSEL0PXA28iRlQwAwnZzADCpiTEocC1YBf8rtAkctIx5pPoHQL2hDbUkgRKWgmAH0ww8ilxvOz1pY4ArQA1vq+NJEci+KfQO2NSAvaENtSSBEpSH4AHs7lOS4gA2gHHLK8IpG8aWRBG4FAMwvaEdtSSBEpSJ4jb5dsujB7VN6zthyRPKsFNIdL3Oj68jLJ2zorUmAopIgUFFuAn8h7F7kbc6jIm0s+Raw0iLx/PzqAKphXsUmhpZAiUlC8g/fX4+0DvregFhEr3A7UJG/f1wbwAnlfDE4KBIUUkYJiJeffeC23AtGVPmIfwcA8oDS5DyrPAndZXZDYjUKKSEGRYkEbDovaEbFKecwAXvXv55f6VHJifg+/Djzj47rEFhRSRAqKUIvaCbOoHRGrxGP28M0Ampy1PSuUAIRjzmHZCgzOz+LEn7TirEhBURHYiHcTXzOBKyypRsRaIcA9fz82YPauHMUM5+WAm4DifqtO/EQhRaSg6A7M9rKNQOBO70sR8ak6fz+kyNNwj0hBcSsQ48X5gZi/pUZbU46IiK8ppIgUFIGYq83m9V9tJjDAunJERHxNIUWkIHkUaE3eVukcDTS2thwREV9SSBEpSIKBOUBLcvavN+vKiBHAcF8VJSLiGwopIgVNBPA/4Gn+mV9y7r/krCnxNYBP0cqcIlIgKaSIFETBmCtu/oUZQm7AXAwrDjOY3AUsBTahVTlFpMDSJcgiBVkwZghREBGRQkg9KSIiImJLCikiIiJiSwopIiIiYksKKSIiImJLCikiIiJiSwopIiIiYksKKSIiImJLCikiIiJiSwopIiIiYksKKSIiImJLCilie5lkcoITGBj+LkVERPKRQorY0ja2MYQhlKIUQQQRTjhBBNGEJnzMx6ST7u8SRUTExxRSxFb+4A8SSKA61ZnABI5y1LPPhYs1rOE+7qMc5Xid19W7IiJSiCmkiG1sYAONaMQiFgHmMM+53LgBSCGFoQzlQR70bBMRkcJFIUVsYS97SSCBoxzFhSvH573Lu4xghA8rExERf1FIEVsYxrBcB5QsYxnLetb7oCoREfEnhRTxuySS+IqvLji8kxOBBDKJSRZXJSIi/qaQIn73Hu95NQE2k0w+4ANSSbWwKhER8TeFFPG7T/jE68mv6aQzj3kWVSQiInagkCJ+d4ADXrfhwMFBDlpQjYiI2IVCivhdXibLnsuBgzOcsaAaERGxC4UU8bsoorxuw42bkpT0vhgREbENhRTxu7a0JZBAr9pw4KAVrSyqSERE7EAhRfyuP/3zfPkxgBMn7WhHZSpbWJWIiPibQor4XQMa0JjGBOTx29GFi4EMtLgqERHxN4UUsYWXeAkHjlyf58RJa1rTnvY+qEpERPxJIUVsoQ1teJ/3cfz9JyecOLmaq5nDHJw4fVyhiIjkN4UUsY0e9GAWswgj7JJhJWuSbRvasIxlllwdJCIi9qOQIrbSkY4kkcR4xlOVquftDySQrnRlOcv5H/8jkkg/VCkiIvnBYRhG3m+aUkikpaURGRlJamoqERER/i5H/mZgsI51JJFEOulEEUUd6lCa0v4uTURE/ubLz1Db96Ts27ePe++9l+joaMLCwqhduzarV6/27DcMg5EjR1KuXDnCwsJISEhgx44dfqxYrOLAQX3qczM3czu3cwM3KKCIiBQhtg4pR48epUWLFgQFBfHdd9+xZcsWXn31VUqW/Gdl0XHjxvHWW28xefJkVqxYQfHixWnXrh3p6el+rFxERES8ZevhnieffJKlS5fy008/XXC/YRjExcUxbNgwHn30UQBSU1OJiYlh+vTpdO3aNUdfR8M9IiIieVNkh3u+/vprGjVqxJ133knZsmWpX78+U6ZM8ezftWsXycnJJCQkeLZFRkbStGlTli9fftF2T58+TVpaWraHiIiI2IutQ8rvv//OpEmTqFq1KvPmzeOhhx7i4Ycf5oMPPgAgOTkZgJiYmGznxcTEePZdyJgxY4iMjPQ84uPjffciREREJE+8u6ubj7ndbho1asSLL74IQP369dm0aROTJ0+mR48eeW53+PDhDB061PM8LS1NQUVECjcXsBjYA5wEIoDaQF1/FiVyabYOKeXKlaNmzZrZttWoUYP//ve/AMTGxgKwf/9+ypUr5zlm//791KtX76LthoSEEBISYn3BIiLn2MUu/o//4xCHcOMmmmj+xb+oSc3Ln2yFg8D7wARg39/bHEDWbMTGwCDgTiA0f0oSySlbh5QWLVqwbdu2bNu2b9/OlVdeCUClSpWIjY0lMTHRE0rS0tJYsWIFDz30UH6XKyICgBs33/EdE5jAPOYB/6yU7MKFGzetaMUgBnEbt3n2We5roCtwGnCftf3syyXWAN2Bp4H/AdV8U4pIXth6TsqQIUP4+eefefHFF9m5cyczZ87k3XffZcCAAQA4HA4GDx7MCy+8wNdff83GjRvp3r07cXFxdOrUyb/Fi0iRdIpT3Mmd3MItzGc+xt9/zvz9x/13WljGMrrQhba0JYUU6wv5DOgEpJM9oJwra9+fQFPgV+tLEckrW1+CDDB37lyGDx/Ojh07qFSpEkOHDqVv376e/YZh8Mwzz/Duu++SkpJCy5YtmThxItWq5fzXAV2CLCJWyCCD9rRnMYs9YeRynDipSU2WspQSlLCmkBVAS8x5KLn5Ce8EygEbQbfEkpzy5Weo7UNKflBIEREr9Kc/7/BOjgNKFidOOtCBOcyxppAOwDzMkJJbDuAVYOjlDhQxFdl1UkRECopkkpnClFwHFDDnqXzN12xms/eF7Aa+I28BJct4Lj1EJJJPFFJERCzwPu/nKaBkCSSQSUzyvpB38O4nu4EZdH7wvhQRbymkiIh4yY2bt3nbq5CSSSbTmMYJTnhXzFK860UB87rPn71sQ8QCCikiIl46whGSSPK6nZOc5Hd+97YY7znAFxccieSWQoqIiJdSSbVPW1YtyKb1LsUGFFJERLxUjGL2aas83v9kdwGxXrYhYgGFFBERL0UTTTDBlrQVR5x3DdyDNVfm3GlBGyJeUkgREfFSMMHcwz1eLW/vxEkCCcR624XRCSjtxfmBwG3gbVYSsUKe/kUlJiaSmJjIgQMHcLuzR/apU6daUpiISEHSn/5MZ3qez3fhYhCDvC8kGOgPvEDeelQygQHelyFihVz3pIwaNYobb7yRxMREDh06xNGjR7M9RESKosY0piEN89Sb4sRJPPF0oIM1xTwJNCT3v4Y6gMFAG2vKEPFWrv81TZ48menTp3Pffff5oh4RkQLrMz6jMY1JIw1XDhcrCSCAIIKYzWycOK0pJAz4FmgHrCPnPSq9MJfEF7GJXPekZGRk0Lx5c1/UIiJSoF3FVSxkIaUolaPA4cRJcYrzPd/TgAbWFlMa+BFz6CcUs5fEcV4BpljgLeC9s7aJ2ECuQ0qfPn2YOXOmL2oRESnw6lKXNazhXu4liCACLvBjNoAAnDi5jdtYyUqu4zrfFFMc8z48+//+bx2gJGZoKYM5rDML2AsM4vwQI+Jnub4L8iOPPMKHH35InTp1qFOnDkFBQdn2v/baa5YWmB90F2QR8YXDHGY60/mKrzjIQVy4KE1pOtCBPvTx/nJjERvw5WdorkNKmzYXn1HlcDhYsGCB10XlN4UUERGRvPHlZ2iuJ84uXLjQ0gJERERELsSrxdz+/PNP/vzzT6tqEREREfHIdUhxu90899xzREZGcuWVV3LllVcSFRXF888/f97CbiIiIiJ5levhnhEjRvD+++8zduxYWrRoAcCSJUt49tlnSU9PZ/To0ZYXKSIiIkVPrifOxsXFMXnyZP79739n2z5nzhz69+/Pvn37LC0wP2jirIiISN748jM018M9R44coXr16udtr169OkeOHLGkKBEREZFch5S6desyYcKE87ZPmDCBunXrWlKUiIiISK7npIwbN44OHTrwww8/0KxZMwCWL1/O3r17+fbbby0vUERERIqmXPekXHfddWzfvp3bbruNlJQUUlJSuP3229m2bRutWrXyRY0iIiJSBOV64mxhpImzNmEYcPgwHDkCDgdER0OpUv6uSkRELsHvK85u2LCBa665hoCAADZs2HDJY+vUqWNJYVKEnDwJn34Kb70F69dn39ekCQwaBHfeCSEh/qlPRET8Ikc9KQEBASQnJ1O2bFkCAgJwOBxc6DSHw4HL5fJJob6knhQ/mjoVhgyBtDQICIBzFwTM2layJEycCF27+qdOERG5IL/3pOzatYsyZcp4/l/EEi+8AE8//c/zC61YnLUtJQXuvhv274dHHsmX8kRExL9yFFKuvPJKz///8ccfNG/enMDA7KdmZmaybNmybMeKXNR772UPKJeT1XM3eDDExKhHRUSkCMj1xFmn00lSUhJly5bNtv3w4cOULVtWwz1yeceOQWysORcltxwOiIqCpCTNURERsQFbrThrGAYOh+O87YcPH6Z48eKWFCWF3IwZcOpU3s41DDh6FL780tqaRETEdnK8mNvtt98OmJNje/bsSchZv8W6XC42bNhA8+bNra9QChfDMK/i8UZAAIwfD926WVOTiIjYUo5DSmRkJGD2pJQoUYKwsDDPvuDgYK699lr69u1rfYVSuOzdC1u3eteG2w0rVpjrqWgdFRGRQivHIWXatGkAVKxYkUcffVRDO5I3hw5Z15ZCiohIoZbre/c888wzvqhDJPe0WLKISKGWo5DSoEEDEhMTKVmyJPXr17/gxNksa9eutaw4KYSio61rS70oIiKFWo5CSseOHT0TZTt16uTLeqSwq1ABqlSB337Le09IQADUrWtt4BEREdvRDQbROin5bvx4c9VYb771pk2Dnj0tK0lERPLGVuuk7N27lz///NPzfOXKlQwePJh3333X0sKkEOve3buF2CIj4a67rKtHRERsKdch5Z577mHhwoUAJCcnk5CQwMqVKxkxYgTPPfec5QVKIRQZCePG5f38N96Asy6BFxGRwinXIWXTpk00adIEgM8//5zatWuzbNkyZsyYwfTp062uTwqrQYPgiSdyf94LL2iYR0SkiMh1SDlz5oxnEu0PP/zAv//9bwCqV69OUlKStdVJ4faf/0DFiubQj8NhPs6Vtb1YMfOmhCNG5HuZIiLiH7kOKbVq1WLy5Mn89NNPzJ8/n/bt2wPw119/Ea2rLSQ3Xn0VvvkG9u+HN9+Eq646/5jq1WHSJPOY3r3zv0YREfGbXF/ds2jRIm677TbS0tLo0aMHU6dOBeA///kPv/76K1999ZVPCvUlXd3jBxs3mqvPtmnzzzbDgD174PBhs/ckOhri4y/cwyIiIrlnGPDTT/D227BggXlXeqcTSpeGu++GBx80e7hzwZefoXm6BNnlcpGWlkbJkiU923bv3k2xYsUoW7aspQXmB4WUfOZ2w5YtcM01/q5ERKTomDsXHnsMfv0VAgMhMzP7fqfT/Pl8003mUhGVK+eoWduFFICDBw+ybds2AK6++mrKlCljaWH5SSEln7nd5oJsIiKSP95+27xgAS6/RpXTaV6FOX8+NGhw2aZttU7KiRMnuP/++ylXrhytW7emdevWxMXF0bt3b06ePGlpcVJIKaCIiOSfGTNg4EAznOSkX8LlgtRUSEgwVwf3o1x/WgwdOpTFixfzzTffkJKSQkpKCnPmzGHx4sUMGzbMFzWKiIhIXhw+DPffn/vzXC5zvkqfPtbXlAu5Hu4pXbo0X375Jddff3227QsXLqRLly4cPHjQyvryhYZ7RESkUHrlFXNNKrc7721s3WpeaXkRthruOXnyJDExMedtL1u2rIZ7RERE7MLtNifAehNQAgPNZSD8JNchpVmzZjzzzDOkp6d7tp06dYpRo0bRrFkzS4sTERGRPFq92lzWwRuZmfDRR9bUkweBuT3hjTfeoF27dpQvX566desCsH79ekJDQ5k3b57lBYqIiEgeJCdb087Ro+YcFafTmvZyIdchpXbt2uzcuZOZM2eydetWAO6++266detGmG76JiIiYg+nT1vXVmam/UPKzz//zDfffENGRgY33HADffw861dEREQu4qwFV70SHGzeY80PchxSvvzyS+666y7CwsIICgritdde46WXXuLRRx/1ZX0iIiKSF/XrQ1AQnDmT9zacTrj2WutqyqUcT5wdM2YMffv2JTU1laNHj/LCCy/w4osv+rI2ERERyavoaLjrLvMKnbxyuf5ZqdYPcrxOSnh4OOvWraNKlSoAZGRkULx4cfbt21cg79dzNq2TIiIihdLPP4M3V96WKQP79pk9Mhdhi3VSTp48me2LBwcHExoayvHjxy0tSERERCzStKl5w8C8Tnp94YVLBhRfy1Uf0HvvvUd4eLjneWZmJtOnT6d06dKebQ8//LB11YmIiEjeORzw2WfQqhVs2mQO3+TUo49Cv36+qy0HcjzcU7FiRRwOx6Ubczj4/fffLSksP2m4R0RECrW0NLjjDvPOxoGB5iXFF+J0mivUjh4NTz5phpzLNu27z9Ac96Ts3r3b0i8sIiIi+SQiAubNg0WL4O23Ydas85fLj4gwe04efBCuusovZZ7Liym/IiIiUmA4HNCmjfn46y9YtsxcTfb0afjyS/juO7DZoqwKKSIiIkVNXJw5/JNl507bBRTIww0GRUREpJCpWdPfFVxQjkPKX3/95cs6RERExF8KekipVasWM2fO9GUtIiIi4g8FPaSMHj2aBx54gDvvvJMjR474siYRERHJT6VK+buCC8pxSOnfvz8bNmzg8OHD1KxZk2+++caXdYmIiEgRl6ureypVqsSCBQuYMGECt99+OzVq1CDwnBsXrV271tICRUREpGjK9SXIf/zxB1999RUlS5akY8eO54UUERERESvkKmFMmTKFYcOGkZCQwObNmylTpoyv6hIREZEiLschpX379qxcuZIJEybQvXt3X9YkIiIikvOQ4nK52LBhA+XLl/dlPSIiIiJALkLK/PnzfVmHiIiISDZaFl9ERERsSSFFREREbEkhRURERGxJIUVERERsSSFFREREbEkhRURERGxJIUVERERsqUCFlLFjx+JwOBg8eLBnW3p6OgMGDCA6Oprw8HA6d+7M/v37/VekiIiIWKLAhJRVq1bxzjvvUKdOnWzbhwwZwjfffMMXX3zB4sWL+euvv7j99tv9VKWIiIhYpUCElOPHj9OtWzemTJlCyZIlPdtTU1N5//33ee2117jhhhto2LAh06ZNY9myZfz8889+rFhERES8VSBCyoABA+jQoQMJCQnZtq9Zs4YzZ85k2169enUqVKjA8uXLL9re6dOnSUtLy/YQERERe8nxvXv85dNPP2Xt2rWsWrXqvH3JyckEBwcTFRWVbXtMTAzJyckXbXPMmDGMGjXK6lJFRETEQrbuSdm7dy+PPPIIM2bMIDQ01LJ2hw8fTmpqquexd+9ey9oWERERa9g6pKxZs4YDBw7QoEEDAgMDCQwMZPHixbz11lsEBgYSExNDRkYGKSkp2c7bv38/sbGxF203JCSEiIiIbA8RERGxF1sP97Rt25aNGzdm29arVy+qV6/OE088QXx8PEFBQSQmJtK5c2cAtm3bxp49e2jWrJk/ShYRERGL2DqklChRgmuuuSbbtuLFixMdHe3Z3rt3b4YOHUqpUqWIiIhg0KBBNGvWjGuv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M8fYsGGD0bFjR10O64UePXoYV1xxhecS5K+++sooXbq08fjjj3uO0XvunWPHjhm//PKL8csvvxiA8dprrxm//PKL8ccffxiGkbP3t3379kb9+vWNFStWGEuWLDGqVq2qS5Bza/z48UaFChWM4OBgo0mTJsbPP//s75IKDeCCj2nTpnmOOXXqlNG/f3+jZMmSRrFixYzbbrvNSEpK8l/RhdC5IUXvufW++eYb45prrjFCQkKM6tWrG++++262/W6323j66aeNmJgYIyQkxGjbtq2xbds2P1Vb8KWlpRmPPPKIUaFCBSM0NNSoXLmyMWLECOP06dOeY/See2fhwoUX/Pndo0cPwzBy9v4ePnzYuPvuu43w8HAjIiLC6NWrl3Hs2LFc1eEwjLOW6BMRERGxiSI7J0VERETsTSFFREREbEkhRURERGxJIUVERERsSSFFREREbEkhRURERGxJIUVERERsSSFFREREbEkhRUQKnOnTpxMVFXXZ4xwOB7Nnz/Z5PSLiGwopInJRLpeL5s2bc/vtt2fbnpqaSnx8PCNGjLjouddffz0OhwOHw0FoaCg1a9Zk4sSJltR11113sX37ds/zZ599lnr16p13XFJSEjfddJMlX1NE8p9CiohclNPpZPr06Xz//ffMmDHDs33QoEGUKlWKZ5555pLn9+3bl6SkJLZs2UKXLl0YMGAAn3zyidd1hYWFUbZs2cseFxsbS0hIiNdfT0T8QyFFRC6pWrVqjB07lkGDBpGUlMScOXP49NNP+fDDDwkODr7kucWKFSM2NpbKlSvz7LPPUrVqVb7++msA9uzZQ8eOHQkPDyciIoIuXbqwf/9+z7nr16+nTZs2lChRgoiICBo2bMjq1auB7MM906dPZ9SoUaxfv97TczN9+nTg/OGejRs3csMNNxAWFkZ0dDT9+vXj+PHjnv09e/akU6dOvPLKK5QrV47o6GgGDBjAmTNnLHgnRSS3Av1dgIjY36BBg5g1axb33XcfGzduZOTIkdStWzfX7YSFhZGRkYHb7fYElMWLF5OZmcmAAQO46667WLRoEQDdunWjfv36TJo0CafTybp16wgKCjqvzbvuuotNmzbx/fff88MPPwAQGRl53nEnTpygXbt2NGvWjFWrVnHgwAH69OnDwIEDPaEGYOHChZQrV46FCxeyc+dO7rrrLurVq0ffvn1z/XpFxDsKKSJyWQ6Hg0mTJlGjRg1q167Nk08+mavzXS4Xn3zyCRs2bKBfv34kJiayceNGdu3aRXx8PAAffvghtWrVYtWqVTRu3Jg9e/bw2GOPUb16dQCqVq16wbbDwsIIDw8nMDCQ2NjYi9Ywc+ZM0tPT+fDDDylevDgAEyZM4NZbb+Wll14iJiYGgJIlSzJhwgScTifVq1enQ4cOJCYmKqSI+IGGe0QkR6ZOnUqxYsXYtWsXf/75Z47OmThxIuHh4YSFhdG3b1+GDBnCQw89xNatW4mPj/cEFICaNWsSFRXF1q1bARg6dCh9+vQhISGBsWPH8ttvv3lV/9atW6lbt64noAC0aNECt9vNtm3bPNtq1aqF0+n0PC9XrhwHDhzw6muLSN4opIjIZS1btozXX3+duXPn0qRJE3r37o1hGJc9r1u3bqxbt45du3Zx4sQJXnvtNQICcvZj59lnn2Xz5s106NCBBQsWULNmTWbNmuXtS7msc4eUHA4Hbrfb519XRM6nkCIil3Ty5El69uzJQw89RJs2bXj//fdZuXIlkydPvuy5kZGRVKlShSuuuCJbOKlRowZ79+5l7969nm1btmwhJSWFmjVrerZVq1aNIUOG8L///Y/bb7+dadOmXfDrBAcH43K5LllLjRo1WL9+PSdOnPBsW7p0KQEBAVx99dWXfS0ikv8UUkTkkoYPH45hGIwdOxaAihUr8sorr/D444+ze/fuPLWZkJBA7dq16datG2vXrmXlypV0796d6667jkaNGnHq1CkGDhzIokWL+OOPP1i6dCmrVq2iRo0aF2yvYsWK7Nq1i3Xr1nHo0CFOnz593jHdunUjNDSUHj16sGnTJhYuXMigQYO47777PPNRRMReFFJE5KIWL17M22+/zbRp0yhWrJhn+wMPPEDz5s1zPOxzLofDwZw5cyhZsiStW7cmISGBypUr89lnnwHm+iyHDx+me/fuVKtWjS5dunDTTTcxatSoC7bXuXNn2rdvT5s2bShTpswF12IpVqwY8+bN48iRIzRu3Jg77riDtm3bMmHChFzXLyL5w2Hk5SeMiIiIiI+pJ0VERERsSSFFREREbEkhRURERGxJIUVERERsSSFFREREbEkhRURERGxJIUVERERsSSFFREREbEkhRURERGxJIUVERERsSSFFREREbOn/AXCujA45exyMAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "render_history(hist, skip_frames=50)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Test manual behavior for an agent\n", - "\n", - "Need to set all of its behaviors to manual." - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [], - "source": [ - "ag_idx = 9\n", - "manual_behaviors = jnp.array([Behaviors.MANUAL.value, Behaviors.MANUAL.value,])\n", - "manual_color = jnp.array([0., 0., 0.])\n", - "manual_motors = jnp.array([1., 1.])\n", - "\n", - "behaviors = state.agents.behavior.at[ag_idx].set(manual_behaviors)\n", - "colors = state.agents.color.at[ag_idx].set(manual_color)\n", - "motors = state.agents.motor.at[ag_idx].set(manual_motors)\n", - "\n", - "agents = state.agents.replace(behavior=behaviors, color=colors, motor=motors)\n", - "state = state.replace(agents=agents)" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": {}, - "outputs": [], - "source": [ - "n_steps = 5_000\n", - "hist = []\n", - "\n", - "for i in range(n_steps):\n", - " state = env.step(state)\n", - " hist.append(state)" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAikAAAIjCAYAAADGCIt4AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8g+/7EAAAACXBIWXMAAA9hAAAPYQGoP6dpAABizUlEQVR4nO3dZ3hU1d6G8XtKKiEJNUVCUUCKNGlSFCkKHkQpiihKEfBIU8SKvGIXxS4ICEfBAiIWqkc4GJogUqUjoAQpEkAgCQESSGa/HwZGAgSSmZ3MTvL8uOaC2WXNf4YyD2utvbbNMAwDEREREYux+7sAERERkUtRSBERERFLUkgRERERS1JIEREREUtSSBERERFLUkgRERERS1JIEREREUtSSBERERFLUkgRERERS1JIESlEevXqRcWKFf1dhoiIKRRSRCzOZrPl6LF48WJ/l3pFY8eOZfLkyf4u44r69euHzWbj9ttvv2hfamoqQ4YMoVy5cgQFBVG9enXGjRt30XGTJ0/O9vcqMTHxouNnz57N9ddfT3BwMOXLl+f5558nIyMjT96fSEHh9HcBInJ5n3/+eZbnn332GQsWLLhoe/Xq1Zk4cSIulys/y8uVsWPHUrp0aXr16uXvUrK1Zs0aJk+eTHBw8EX7MjMzadu2LWvWrGHgwIFUqVKF+fPnM2DAAI4dO8azzz570TkvvfQSlSpVyrItMjIyy/MffviBjh07cvPNNzN69Gg2bdrEK6+8wqFDhy4ZgESKDENECpSBAwcaBfWvbs2aNY0WLVr4u4xsuVwuo0mTJsaDDz5oVKhQwWjfvn2W/dOnTzcA4+OPP86yvUuXLkZwcLBx8OBBz7ZJkyYZgLF69eorvm6NGjWMOnXqGGfOnPFsGz58uGGz2Yxt27b5+K5ECi4N94gUIhfOSdm9ezc2m4233nqLDz/8kKuvvprQ0FBuvfVW9u7di2EYvPzyy5QrV46QkBDuvPNOjh49elG7P/zwAzfeeCPFihWjePHitG/fni1btmQ5JjExkd69e3uGQWJiYrjzzjvZvXs3ABUrVmTLli0sWbLEM+xx8803e85PSkpiyJAhxMXFERQUROXKlXnjjTey9Ayd/37effddKlSoQEhICC1atGDz5s1Z6jlz5gy//fYbBw4cyPHn9/nnn7N582ZeffXVS+7/6aefAOjWrVuW7d26dSMtLY1Zs2Zd8rzjx4+TmZl5yX1bt25l69atPPTQQzid/3RuDxgwAMMw+Oabb3Jcv0hho+EekSJgypQpnD59msGDB3P06FFGjRpF165dadWqFYsXL+bpp5/m999/Z/To0TzxxBN88sknnnM///xzevbsSdu2bXnjjTc4efIk48aNo3nz5vz666+eUNSlSxe2bNnC4MGDqVixIocOHWLBggXs2bOHihUr8t577zF48GDCwsIYPnw4AFFRUQCcPHmSFi1asH//fv79739Tvnx5fv75Z4YNG8aBAwd47733sryfzz77jOPHjzNw4EDS0tJ4//33adWqFZs2bfK0uX//fqpXr07Pnj1zNA/m+PHjPP300zz77LNER0df8pj09HQcDgeBgYFZtoeGhgKwdu1a+vXrl2Vfy5YtSU1NJTAwkLZt2/L2229TpUoVz/5ff/0VgAYNGmQ5LzY2lnLlynn2ixRJ/u7KEZHcudxwT8+ePY0KFSp4nickJBiAUaZMGSMpKcmzfdiwYQZw0RDDvffeawQGBhppaWmGYRjG8ePHjcjISKNfv35ZXicxMdGIiIjwbD927JgBGG+++eZla89uuOfll182ihUrZuzYsSPL9meeecZwOBzGnj17sryfkJAQY9++fZ7jVq5caQDGY489dtF779mz52VrOueJJ54wKlWq5Hnvlxruefvttw3A+Omnny6qEzBuv/12z7avvvrK6NWrl/Hpp58aM2bMMP7v//7PCA0NNUqXLu15P4ZhGG+++aYBZNl2TsOGDY0bbrghR/WLFEYa7hEpAu6++24iIiI8zxs3bgzA/fffn2WIoXHjxpw+fZr9+/cDsGDBApKSkrj33nv5+++/PQ+Hw0Hjxo1ZtGgRACEhIQQGBrJ48WKOHTuW6/q+/vprbrzxRkqUKJHlddq0aUNmZiZLly7NcnzHjh256qqrPM8bNWpE48aN+e9//+vZVrFiRQzDyFEvyo4dO3j//fd58803CQoKyva4++67j4iICB588EEWLFjA7t27mTBhAmPHjgXg1KlTnmO7du3KpEmT6NGjBx07duTll19m/vz5HDlyJMtw0rlzLvW6wcHBWdoUKWo03CNSBJQvXz7L83OBJS4u7pLbzwWNnTt3AtCqVatLthseHg64v2DfeOMNHn/8caKiorjhhhu4/fbb6dGjR7ZDJ+fbuXMnGzdupEyZMpfcf+jQoSzPzx8uOadq1apMnz79iq91KY8++ihNmzalS5culz0uOjqa2bNn88ADD3DrrbcC7s9g9OjR9OzZk7CwsMue37x5cxo3bsyPP/7o2RYSEgK4h5IulJaW5tkvUhQppIgUAQ6HI1fbDcMA8Exa/fzzzy8ZNs7vhRkyZAgdOnRg5syZzJ8/n+eee46RI0eycOFC6tWrd9n6XC4Xt9xyC0899dQl91etWvWy5/ti4cKFzJs3j++++84zyRcgIyODU6dOsXv3bkqWLOkJZDfddBO7du1i06ZNnDhxgjp16vDXX3/luM64uDi2b9/ueR4TEwPAgQMHLgqNBw4coFGjRr6+RZECSyFFRLJ1zTXXAFC2bFnatGmTo+Mff/xxHn/8cXbu3EndunV5++23+eKLLwD3wnTZnZeampqj14B/enjOt2PHDq9W292zZw8AnTt3vmjf/v37qVSpEu+++y5DhgzxbHc4HNStW9fz/FzPSE7q37VrV5Yeo3PtrFmzJksg+euvv9i3bx8PPfRQbt6OSKGiOSkikq22bdsSHh7Oa6+9xpkzZy7af/jwYcB9dU5aWlqWfddccw3FixfPMoxRrFgxkpKSLmqna9eurFixgvnz51+0Lykp6aKVV2fOnOmZNwOwatUqVq5cyW233ebZltNLkFu1asWMGTMuepQpU4YGDRowY8YMOnTokO35hw8f5o033qB27dpZQsq5z+Z8//3vf1m7di3t2rXzbKtZsybVqlVjwoQJWS5THjduHDabjbvuuuuy9YsUZupJEZFshYeHM27cOB544AGuv/56unXrRpkyZdizZw/ff/89zZo1Y8yYMezYsYPWrVvTtWtXatSogdPpZMaMGRw8eDDLmiL169dn3LhxvPLKK1SuXJmyZcvSqlUrnnzySWbPns3tt99Or169qF+/PidOnGDTpk1888037N69m9KlS3vaqVy5Ms2bN6d///6kp6fz3nvvUapUqSzDRTm9BLl8+fIXzdkB9/BVVFQUHTt2zLK9RYsWNGnShMqVK5OYmMiECRNITU1l7ty52O3//L+vadOm1KtXjwYNGhAREcG6dev45JNPiIuLu2hl2jfffJM77riDW2+9lW7durF582bGjBlD3759qV69ek5/u0QKHYUUEbms++67j9jYWF5//XXefPNN0tPTueqqq7jxxhvp3bs34J5nce+99xIfH8/nn3+O0+mkWrVqTJ8+Pctk1BEjRvDnn38yatQojh8/TosWLWjVqhWhoaEsWbKE1157ja+//prPPvuM8PBwqlatyosvvpjlyiSAHj16YLfbee+99zh06BCNGjVizJgxnvkdeal+/fp8/fXX7N+/n/DwcG655RZefvllrr766izH3XPPPXz//ff873//4+TJk8TExNCvXz+ef/55z1ou59x+++189913vPjiiwwePJgyZcrw7LPPMmLEiDx/PyJWZjPOzZATEbG43bt3U6lSJd58802eeOIJf5cjInlMc1JERETEkhRSRERExJIUUkRERMSS/BpSli5dSocOHYiNjcVmszFz5sws+w3DYMSIEcTExBASEkKbNm0uWh/h6NGjdO/enfDwcCIjI+nTpw+pqan5+C5EJL+cW+pe81FEiga/hpRzqzV++OGHl9w/atQoPvjgA8aPH8/KlSspVqwYbdu2zbIeQ/fu3dmyZQsLFixg7ty5LF26VIsfiYiIFAKWubrHZrMxY8YMz5oEhmEQGxvL448/7vlfU3JyMlFRUUyePJlu3bqxbds2atSowerVqz23OZ83bx7/+te/2LdvH7Gxsf56OyIiIuIjy66TkpCQQGJiYpYVHCMiImjcuDErVqygW7durFixgsjISE9AAfey1Ha7nZUrV9KpU6dLtp2enp5lFUyXy8XRo0cpVapUtst2i4iIyMUMw+D48ePExsZmWdDQDJYNKYmJiQAXLXoUFRXl2ZeYmEjZsmWz7Hc6nZQsWdJzzKWMHDmSF1980eSKRUREiq69e/dSrlw5U9u0bEjJS8OGDWPo0KGe58nJyZQvX569e/d67nQqIiIiV5aSkkJcXBzFixc3vW3LhpRzt4U/ePBglqWuDx486LlraHR0NIcOHcpyXkZGBkePHr3kbeXPCQoKIigo6KLt4eHhCikiIpL/0oEjQBoQCZQACtjsg7yYLmHZdVIqVapEdHQ08fHxnm0pKSmsXLmSJk2aANCkSROSkpJYu3at55iFCxficrlo3LhxvtcsIiKSYwawHLgPKA5cBVwDlAIqAm/iDi5FmF97UlJTU/n99989zxMSEli/fj0lS5akfPnyDBkyhFdeeYUqVapQqVIlnnvuOWJjYz1XAFWvXp127drRr18/xo8fz5kzZxg0aBDdunXTlT0iImJdW4F7gM24v4kzLti/B3gGGA48CrwOOPKzQGvwa0hZs2YNLVu29Dw/N0/k3K3Vn3rqKU6cOMFDDz1EUlISzZs3Z968eQQHB3vOmTJlCoMGDaJ169bY7Xa6dOnCBx98kO/vRUREJEdWALcCp84+vzCgnOM6+3gb2AF8AwTkeXWWYpl1UvwpJSWFiIgIkpOTs52TkpmZyZkzZ/K5Mjmfw+HA6XTqMnERKbh2Ag2B47gDSE7ZgF7Ax1hurkpOvkO9ZdmJs1aSmprKvn37UJ7zv9DQUGJiYggMDPR3KSIiufcEkEruAgq4569MAvoAzcwuyroUUq4gMzOTffv2ERoaSpkyZfS/eD8xDIPTp09z+PBhEhISqFKliumLBomI5Km9wBzcgcMbTmAsCinyjzNnzmAYBmXKlCEkJMTf5RRpISEhBAQE8Oeff3L69Oksc5NERCxvAu5rajO9PD8DmA68C5S9wrGFhEJKDnnbg2IYsHo1zJkDf/8NLheUKgVt28JNN4E6ZnJHvSciUmB9i/cB5ZwMYD7wgO/lFAQKKXnk9Gn4/HMYPRo2bACn859AYhgwciRUrQqPPAK9e0NoqH/rFRGRPPa3CW3YKVJrp+i/pXng2DFo1Qr69oVNm9zbMjLgzBn3I+Ps5WY7d8LgwdCkCRw44L96RUQkH+R2smxet1MAKKSYLDUVWraEX35xP3dd5g+TYbgfW7dCs2bu4SARESmkSpnQhgsoaUI7BYRCisn69oXNmyEzF+OOGRmwZw907Zp3dfmTzWZj5syZ/i5DRMS/2uP7qrE2oLUJtRQQCikm2r0bpk/PXUA5JzMTFi2CdetML0tERKzgYXybOOsEOgBx5pRTECikmOijj8CXi0+cTvjwQ/PqmTdvHs2bNycyMpJSpUpx++2388cff3j2//zzz9StW5fg4GAaNGjAzJkzsdlsrF+/3nPM5s2bue222wgLCyMqKooHHniAv88bl7r55pt55JFHeOqppyhZsiTR0dG88MILnv0VK1YEoFOnTthsNs/zDRs20LJlS4oXL054eDj169dnzZo15r15ERGrqYq7F8Tb3pQMYJB55RQECikmycx0hxRvelHOyciAKVPg+HFzajpx4gRDhw5lzZo1xMfHY7fb6dSpEy6Xi5SUFDp06ECtWrVYt24dL7/8Mk8//XSW85OSkmjVqhX16tVjzZo1zJs3j4MHD9L1gnGpTz/9lGLFirFy5UpGjRrFSy+9xIIFCwBYvXo1AJMmTeLAgQOe5927d6dcuXKsXr2atWvX8swzzxAQUMRuSiEiRc8o3Pffye3yE3bgdorUUA/oEmTT/P23+6oeX6Wnw59/wnXX+d5Wly5dsjz/5JNPKFOmDFu3bmXZsmXYbDYmTpxIcHAwNWrUYP/+/fTr189z/JgxY6hXrx6vvfZaljbi4uLYsWMHVatWBaB27do8//zzAFSpUoUxY8YQHx/PLbfcQpkyZQCIjIwkOjra086ePXt48sknqVatmuc8EZFC73rcNwrshHvoJydX6tiBRsA0ilzXQhF7u3knJcV6be3cuZN7772Xq6++mvDwcM9Qy549e9i+fTu1a9fOsmpro0aNspy/YcMGFi1aRFhYmOdxLlScP2xUu3btLOfFxMRw6NChy9Y2dOhQ+vbtS5s2bXj99deztCciUqi1BxYBZc4+z27459z2e4CFQLE8rsuCFFJMUszEPzxhYea006FDB44ePcrEiRNZuXIlK1euBOD06dM5Oj81NZUOHTqwfv36LI+dO3dy0003eY67cJjGZrPhuty118ALL7zAli1baN++PQsXLqRGjRrMmDEjl+9QRKSAaob7Xj5fc+l78RQHHgG2A1OBInpXFg33mKR0aQgJgVOnfGvHboerrvK9niNHjrB9+3YmTpzIjTfeCMCyZcs8+6+99lq++OIL0tPTCQoKAv6ZP3LO9ddfz7fffkvFihVxOr3/oxIQEEDmJSbrVK1alapVq/LYY49x7733MmnSJDp16uT164iIFCgBwF1nH38BB4BTQCRwDUU2mJxPPSkmCQyEnj3dV+h4y+mEjh3d9/bxVYkSJShVqhQTJkzg999/Z+HChQwdOtSz/7777sPlcvHQQw+xbds25s+fz1tvvQX8c5+igQMHcvToUe69915Wr17NH3/8wfz58+ndu/clQ0d2KlasSHx8PImJiRw7doxTp04xaNAgFi9ezJ9//sny5ctZvXo11atX9/2Ni4gURLFAfaA5cB0KKGcppJiof/9/lrz3RkYGDBxoTi12u51p06axdu1arrvuOh577DHefPNNz/7w8HDmzJnD+vXrqVu3LsOHD2fEiBEAnnkqsbGxLF++nMzMTG699VZq1arFkCFDiIyMzNWN/t5++20WLFhAXFwc9erVw+FwcOTIEXr0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RETyhUKK1b31lvs+PDnlcEBYGPzwA1Spknd1iYiI5DGFFKtzOODTT+HllyE01N2rcqmelXNzV+rUcS+Hf8MN+VuniIiIySwdUkaOHEnDhg0pXrw4ZcuWpWPHjmzfvj3LMWlpaQwcOJBSpUoRFhZGly5dOHjwoJ8qziM2G/zf/0FionuZ+2rVsu4PCnL3tqxaBWvXQvXq/qlTRETERDbDMGMxjrzRrl07unXrRsOGDcnIyODZZ59l8+bNbN26lWLFigHQv39/vv/+eyZPnkxERASDBg3CbrezfPnyHL9OSkoKERERJCcnEx4enldvx1xpaZCU5A4oERHmLf4mIiKSC3n5HWrpkHKhw4cPU7ZsWZYsWcJNN91EcnIyZcqUYerUqdx1110A/Pbbb1SvXp0VK1ZwQw6HPApkSBEREbGAvPwOLVD//U5OTgagZMmSAKxdu5YzZ87Qpk0bzzHVqlWjfPnyrFixItt20tPTSUlJyfIQERERaykwIcXlcjFkyBCaNWvGddddB0BiYiKBgYFERkZmOTYqKorExMRs2xo5ciQRERGeR1xcXF6WLiIiIl4oMCFl4MCBbN68mWnTpvnc1rBhw0hOTvY89u7da0KFIiIiYiYf1lzPP4MGDWLu3LksXbqUcuXKebZHR0dz+vRpkpKSsvSmHDx4kOjo6GzbCwoKIigoKC9LFhERER9ZuifFMAwGDRrEjBkzWLhwIZUqVcqyv379+gQEBBAfH+/Ztn37dvbs2UOTJk3yu1wRERExkaV7UgYOHMjUqVOZNWsWxYsX98wziYiIICQkhIiICPr06cPQoUMpWbIk4eHhDB48mCZNmuT4yh4RERGxJktfgmzL5p41kyZNolevXoB7MbfHH3+cL7/8kvT0dNq2bcvYsWMvO9xzIV2CLCIi4h2tk5LHFFJERES8o3VSREREpMhRSBERERFLUkgRERERS1JIEREREUtSSBERERFLUkgRERERS1JIEREREUtSSBERERFLUkgRERERS1JIEREREUtSSBERERFLUkgRERERS1JIEREREUtSSBERERFLUkgRERERS1JIEREREUtSSBERERFLUkgRERERS1JIEREREUtSSBERERFLUkgRERERS1JIEREREUtSSBERERFLUkgRERERS1JIEREREUtSSBERERFLUkgRERERS1JIEREREUtSSBERERFLUkgRERERS1JIEREREUtSSBERERFLUkgRERERS1JIEREREUtSSBERERFLUkgRERERS1JIEREREUtSSBERERFLUkgRERERS1JIEREREUtSSBERERFLUkgRERERS1JIEREREUtSSBERERFLUkgRERERS3L6uwARyaXMTDh8GJKTITQUypSB4GB/VyUiYjr1pIgUFPv2wYgREB0NMTFQrRqULw/h4dCzJ6xaBYbh7ypFREyjkCJidWlp0Ls3VKgAr70Gf/+ddf+ZMzB1KjRuDA0bwq5d/qlTRMRkCikiVnbiBLRuDZ99Bi6Xe6jnUjIy3D9v2AANGsDGjflXo4hIHlFIEbGqzEzo2hVWrnQHlJzIyICUFLj1Vti/P2/rExHJYwopIlY1axb897/Z955kJzMTjhxxz18RESnAFFJErGr0aHA4vDs3IwOmTIGkJFNLEhHJTwopIlb022+weHHue1HOd/o0fPqpaSWJiOQ3hRQRK/r+e7D7+NfTMGDmTFPKERHxB4UUESs6csT7oZ7zHTrkexsiIn6ikCJiRTm9mudKtLibiBRgCikiVlSqlG/zUc4pXdr3NkRE/EQhRcSK2rb1vTfFbofbbzenHhERP1BIEbGi2rWhSRPf5qU4HPDgg+bVJCKSzxRSRKxq8GDfhnwaNdJwj4gUaAopIlZ1113QvHnue1McDoiIcPfGPP64+waFIiIFkNPfBYhINgICYPZsaNECtm7NWa+KwwHBwfDDD+7hor/+gi++gHbtoFy5vK9ZRMRE6kkRsbISJWD5cmjf3v3cmc3/K85tr1gRfvnFHVAAYmOhb18ICvrnTskiIgWEQoqI1RUv7r7Z4JYt8PDDEBqadb/N5u4pmTcPduyA6667uI0yZbIPOCIiFmUzDK32lJKSQkREBMnJyYSHh/u7HJHLO3kS/vwTkpPdgSU2VhNkRcRv8vI7VP+1EiloQkOhenV/VyEikuc03CMiIiKWpJAiIiIilqSQIiIiIpakkCIiIiKWpJAiIiIilqSQIiIiIpakkCIiIiKWpJAiIiIilqSQIiIiIpakkCIiIiKWpJAiIiIilqSQIiIiIpakkCIiIiKWpJAiIiIilqSQIiIiIpakkCIiIiKWVGhCyocffkjFihUJDg6mcePGrFq1yt8liYiIiA8KRUj56quvGDp0KM8//zzr1q2jTp06tG3blkOHDvm7NBEREfFSoQgp77zzDv369aN3797UqFGD8ePHExoayieffOLv0kRERMRLTn8X4KvTp0+zdu1ahg0b5tlmt9tp06YNK1asuOQ56enppKene54nJycDkJKSkrfFioiIFDLnvjsNwzC97QIfUv7++28yMzOJiorKsj0qKorffvvtkueMHDmSF1988aLtcXFxeVKjiIhIYXfkyBEiIiJMbbPAhxRvDBs2jKFDh3qeJyUlUaFCBfbs2WP6ByyXlpKSQlxcHHv37iU8PNzf5RQJ+szznz7z/KfPPP8lJydTvnx5SpYsaXrbBT6klC5dGofDwcGDB7NsP3jwINHR0Zc8JygoiKCgoIu2R0RE6A91PgsPD9dnns/0mec/feb5T595/rPbzZ/mWuAnzgYGBlK/fn3i4+M921wuF/Hx8TRp0sSPlYmIiIgvCnxPCsDQoUPp2bMnDRo0oFGjRrz33nucOHGC3r17+7s0ERER8VKhCCn33HMPhw8fZsSIESQmJlK3bl3mzZt30WTa7AQFBfH8889fcghI8oY+8/ynzzz/6TPPf/rM819efuY2Iy+uGRIRERHxUYGfkyIiIiKFk0KKiIiIWJJCioiIiFiSQoqIiIhYUpEPKR9++CEVK1YkODiYxo0bs2rVKn+XVGiMHDmShg0bUrx4ccqWLUvHjh3Zvn17lmPS0tIYOHAgpUqVIiwsjC5duly0MJ947/XXX8dmszFkyBDPNn3m5tu/fz/3338/pUqVIiQkhFq1arFmzRrPfsMwGDFiBDExMYSEhNCmTRt27tzpx4oLtszMTJ577jkqVapESEgI11xzDS+//HKWe8foM/fN0qVL6dChA7GxsdhsNmbOnJllf04+36NHj9K9e3fCw8OJjIykT58+pKam5q4QowibNm2aERgYaHzyySfGli1bjH79+hmRkZHGwYMH/V1aodC2bVtj0qRJxubNm43169cb//rXv4zy5csbqampnmMefvhhIy4uzoiPjzfWrFlj3HDDDUbTpk39WHXhsWrVKqNixYpG7dq1jUcffdSzXZ+5uY4ePWpUqFDB6NWrl7Fy5Upj165dxvz5843ff//dc8zrr79uREREGDNnzjQ2bNhg3HHHHUalSpWMU6dO+bHyguvVV181SpUqZcydO9dISEgwvv76ayMsLMx4//33PcfoM/fNf//7X2P48OHGd999ZwDG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ZF588UU2bNjg6bmZPHkycPFwz6ZNm2jVqhUhISGUKlWKhx56iNTUVM/+Xr160bFjR9566y1iYmIoVaoUAwcO5MyZMyZ8kiKSW05/FyAi1jd48GBmzJjBAw88wKZNmxgxYgR16tTJdTshISGcPn0al8vlCShLliwhIyODgQMHcs8997B48WIAunfvTr169Rg3bhwOh4P169cTEBBwUZv33HMPmzdvZt68efz4448AREREXHTciRMnaNu2LU2aNGH16tUcOnSIvn37MmjQIE+oAVi0aBExMTEsWrSI33//nXvuuYe6devSr1+/XL9fEfGNQoqIXJHNZmPcuHFUr16dWrVq8cwzz+Tq/MzMTL788ks2btzIQw89RHx8PJs2bSIhIYG4uDgAPvvsM2rWrMnq1atp2LAhe/bs4cknn6RatWoAVKlS5ZJth4SEEBYWhtPpJDo6Otsapk6dSlpaGp999hnFihUDYMyYMXTo0IE33niDqKgoAEqUKMGYMWNwOBxUq1aN9u3bEx8fr5Ai4gca7hGRHPnkk08IDQ0lISGBffv25eicsWPHEhYWRkhICP369eOxxx6jf//+bNu2jbi4OE9AAahRowaRkZFs27YNgKFDh9K3b1/atGnD66+/zh9//OFT/du2baNOnTqegALQrFkzXC4X27dv92yrWbMmDofD8zwmJoZDhw759Noi4h2FFBG5op9//pl3332XuXPn0qhRI/r06YNhGFc8r3v37qxfv56EhAROnDjBO++8g92es392XnjhBbZs2UL79u1ZuHAhNWrUYMaMGb6+lSu6cEjJZrPhcrny/HVF5GIKKSJyWSdPnqRXr17079+fli1b8vHHH7Nq1SrGjx9/xXMjIiKoXLkyV111VZZwUr16dfbu3cvevXs927Zu3UpSUhI1atTwbKtatSqPPfYY//vf/+jcuTOTJk265OsEBgaSmZl52VqqV6/Ohg0bOHHihGfb8uXLsdvtXHvttVd8LyKS/xRSROSyhg0bhmEYvP766wBUrFiRt956i6eeeordu3d71WabNm2oVasW3bt3Z926daxatYoePXrQokULGjRowKlTpxg0aBCLFy/mzz//ZPny5axevZrq1atfsr2KFSuSkJDA+vXr+fvvv0lPT7/omO7duxMcHEzPnj3ZvHkzixYtYvDgwTzwwAOe+SgiYi0KKSKSrSVLlvDhhx8yadIkQkNDPdv//e9/07Rp0xwP+1zIZrMxa9YsSpQowU033USbNm24+uqr+eqrrwD3+ixHjhyhR48eVK1ala5du3Lbbbfx4osvXrK9Ll260K5dO1q2bEmZMmUuuRZLaGgo8+fP5+jRozRs2JC77rqL1q1bM2bMmFzXLyL5w2Z48y+MiIiISB5TT4qIiIhYkkKKiIiIWJJCioiIiFiSQoqIiIhYkkKKiIiIWJJCioiIiFiSQoqIiIhYkkKKiIiIWJJCioiIiFiSQoqIiIhYkkKKiIiIWNL/A8vDhQoeHrpWAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "render_history(hist, skip_frames=50)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "venv", - "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.10.12" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -}