diff --git a/blackjax/__init__.py b/blackjax/__init__.py index ef5eabd79..1a078cc91 100644 --- a/blackjax/__init__.py +++ b/blackjax/__init__.py @@ -3,25 +3,32 @@ from blackjax._version import __version__ -from .adaptation.adjusted_mclmc_adaptation import adjusted_mclmc_find_L_and_step_size from .adaptation.chees_adaptation import chees_adaptation -from .adaptation.mclmc_adaptation import mclmc_find_L_and_step_size from .adaptation.meads_adaptation import meads_adaptation from .adaptation.pathfinder_adaptation import pathfinder_adaptation from .adaptation.window_adaptation import window_adaptation +from .adaptation.unadjusted_alba import unadjusted_alba +from .adaptation.unadjusted_step_size import robnik_step_size_tuning +from .adaptation.adjusted_alba import adjusted_alba +from .adaptation.las import las from .base import SamplingAlgorithm, VIAlgorithm from .diagnostics import effective_sample_size as ess from .diagnostics import potential_scale_reduction as rhat -from .mcmc import adjusted_mclmc as _adjusted_mclmc from .mcmc import adjusted_mclmc_dynamic as _adjusted_mclmc_dynamic from .mcmc import barker from .mcmc import dynamic_hmc as _dynamic_hmc +from .mcmc import dynamic_malt as _dynamic_malt from .mcmc import elliptical_slice as _elliptical_slice from .mcmc import ghmc as _ghmc from .mcmc import hmc as _hmc +from .mcmc import uhmc as _uhmc +from .mcmc import malt as _malt from .mcmc import mala as _mala +from .mcmc import pseudofermion as _pseudofermion from .mcmc import marginal_latent_gaussian from .mcmc import mclmc as _mclmc +from .mcmc import mchmc as _mchmc +from .mcmc import underdamped_langevin as _langevin from .mcmc import nuts as _nuts from .mcmc import periodic_orbital, random_walk from .mcmc import rmhmc as _rmhmc @@ -96,12 +103,15 @@ def generate_top_level_api_from(module): # MCMC hmc = generate_top_level_api_from(_hmc) +uhmc = generate_top_level_api_from(_uhmc) +malt = generate_top_level_api_from(_malt) nuts = generate_top_level_api_from(_nuts) rmh = GenerateSamplingAPI(rmh_as_top_level_api, random_walk.init, random_walk.build_rmh) irmh = GenerateSamplingAPI( irmh_as_top_level_api, random_walk.init, random_walk.build_irmh ) dynamic_hmc = generate_top_level_api_from(_dynamic_hmc) +dynamic_malt = generate_top_level_api_from(_dynamic_malt) rmhmc = generate_top_level_api_from(_rmhmc) mala = generate_top_level_api_from(_mala) mgrad_gaussian = generate_top_level_api_from(marginal_latent_gaussian) @@ -114,12 +124,14 @@ def generate_top_level_api_from(module): additive_step_random_walk.register_factory("normal_random_walk", normal_random_walk) mclmc = generate_top_level_api_from(_mclmc) +mchmc = generate_top_level_api_from(_mchmc) +langevin = generate_top_level_api_from(_langevin) adjusted_mclmc_dynamic = generate_top_level_api_from(_adjusted_mclmc_dynamic) -adjusted_mclmc = generate_top_level_api_from(_adjusted_mclmc) +# adjusted_mclmc = generate_top_level_api_from(_adjusted_mclmc) elliptical_slice = generate_top_level_api_from(_elliptical_slice) ghmc = generate_top_level_api_from(_ghmc) barker_proposal = generate_top_level_api_from(barker) - +pseudofermion = generate_top_level_api_from(_pseudofermion) hmc_family = [hmc, nuts] # SMC @@ -165,8 +177,10 @@ def generate_top_level_api_from(module): "meads_adaptation", "chees_adaptation", "pathfinder_adaptation", - "mclmc_find_L_and_step_size", # mclmc adaptation - "adjusted_mclmc_find_L_and_step_size", # adjusted mclmc adaptation "ess", # diagnostics "rhat", + "unadjusted_alba", + "robnik_step_size_tuning", + "adjusted_alba", + "las", ] diff --git a/blackjax/adaptation/__init__.py b/blackjax/adaptation/__init__.py index 53d5fe2b6..bdade7fff 100644 --- a/blackjax/adaptation/__init__.py +++ b/blackjax/adaptation/__init__.py @@ -4,6 +4,8 @@ meads_adaptation, pathfinder_adaptation, window_adaptation, + unadjusted_alba, + unadjusted_step_size, ) __all__ = [ @@ -12,4 +14,6 @@ "window_adaptation", "pathfinder_adaptation", "mclmc_adaptation", + "unadjusted_alba", + "robnik_step_size_tuning", ] diff --git a/blackjax/adaptation/adjusted_alba.py b/blackjax/adaptation/adjusted_alba.py new file mode 100644 index 000000000..a04da52a6 --- /dev/null +++ b/blackjax/adaptation/adjusted_alba.py @@ -0,0 +1,156 @@ +from blackjax.adaptation.step_size import ( + dual_averaging_adaptation, +) +from blackjax.mcmc.adjusted_mclmc_dynamic import rescale +from blackjax.base import AdaptationAlgorithm +from blackjax.types import ArrayLikeTree, PRNGKey +import jax +import jax.numpy as jnp +from typing import Callable +import blackjax +from blackjax.adaptation.unadjusted_alba import unadjusted_alba + + + +def make_random_trajectory_length_fn(random_trajectory_length : bool): + if random_trajectory_length: + integration_steps_fn = lambda avg_num_integration_steps: lambda k: jnp.where(jnp.ceil( + jax.random.uniform(k) * rescale(avg_num_integration_steps) + )==0, 1, jnp.ceil( + jax.random.uniform(k) * rescale(avg_num_integration_steps))).astype('int32') + else: + integration_steps_fn = lambda avg_num_integration_steps: lambda _: jnp.ceil( + avg_num_integration_steps + ).astype('int32') + return integration_steps_fn + +def da_adaptation( + algorithm, + logdensity_fn: Callable, + integration_steps_fn: Callable, + inverse_mass_matrix, + initial_step_size: float = 1.0, + target_acceptance_rate: float = 0.80, + initial_L: float = 1.0, + integrator=blackjax.mcmc.integrators.velocity_verlet, + L_proposal_factor=jnp.inf, +): + + da_init, da_update, da_final = dual_averaging_adaptation(target_acceptance_rate) + kernel = algorithm.build_kernel(integrator=integrator, L_proposal_factor=L_proposal_factor) + + # initial_L = jnp.clip(initial_L, min=initial_step_size+0.01) + + + def step(state, key): + + (adaptation_state, kernel_state), L = state + new_kernel_state, info = kernel( + rng_key=key, + state=kernel_state, + logdensity_fn=logdensity_fn, + step_size=jnp.exp(adaptation_state.log_step_size), + inverse_mass_matrix=inverse_mass_matrix, + integration_steps_fn=integration_steps_fn(L/jnp.exp(adaptation_state.log_step_size)), + ) + + new_adaptation_state = da_update( + adaptation_state, + info.acceptance_rate, + ) + + + return ( + ((new_adaptation_state, new_kernel_state), L), + None, + ) + + def run(rng_key: PRNGKey, position: ArrayLikeTree, num_steps: int = 1000): + + + init_key, rng_key = jax.random.split(rng_key) + + init_kernel_state = algorithm.init(position=position, logdensity_fn=logdensity_fn, random_generator_arg=init_key) + + keys = jax.random.split(rng_key, num_steps) + init_state = da_init(initial_step_size), init_kernel_state + ((adaptation_state, kernel_state), L), info = jax.lax.scan( + step, + (init_state, initial_L), + keys, + + ) + step_size = da_final(adaptation_state) + return ( + kernel_state, + { + "step_size": step_size, + "inverse_mass_matrix": inverse_mass_matrix, + "L": L, + }, + info, + ) + + return AdaptationAlgorithm(run) + + +def adjusted_alba( + unadjusted_algorithm, + logdensity_fn: Callable, + target_eevpd, + v, + adjusted_algorithm, + integrator, + target_acceptance_rate: float = 0.80, + num_alba_steps: int = 500, + alba_factor: float = 0.4, + preconditioning: bool = True, + L_proposal_factor=jnp.inf, + **extra_parameters, + ): + + unadjusted_warmup = unadjusted_alba( + algorithm= unadjusted_algorithm, + logdensity_fn=logdensity_fn, + target_eevpd=target_eevpd, + v=v, + integrator=integrator, + num_alba_steps=num_alba_steps, + alba_factor=alba_factor, + preconditioning=preconditioning, + **extra_parameters) + + def run(rng_key: PRNGKey, position: ArrayLikeTree, num_steps: int = 1000): + + unadjusted_warmup_key, adjusted_warmup_key = jax.random.split(rng_key) + + num_unadjusted_steps = 20000 + + (state, params), adaptation_info = unadjusted_warmup.run(unadjusted_warmup_key, position, num_unadjusted_steps) + + # jax.debug.print("unadjusted params: {params}", params=(params["L"], params["step_size"])) + # jax.debug.print("unadjusted params: {params}", params=params) + + integration_steps_fn = make_random_trajectory_length_fn(random_trajectory_length=True) + + adjusted_warmup = da_adaptation( + algorithm=adjusted_algorithm, + logdensity_fn=logdensity_fn, + integration_steps_fn=integration_steps_fn, + initial_L=params["L"], + initial_step_size=params["step_size"], + target_acceptance_rate=target_acceptance_rate, + inverse_mass_matrix=params["inverse_mass_matrix"], + integrator=integrator, L_proposal_factor=L_proposal_factor, **extra_parameters) + + + + state, params, adaptation_info = adjusted_warmup.run(adjusted_warmup_key, state.position, num_steps) + # jax.debug.print("adjusted params: {params}", params=(params["L"], params["step_size"])) + # raise Exception("stop") + # return None + return state, params, adaptation_info + + return AdaptationAlgorithm(run) + + \ No newline at end of file diff --git a/blackjax/adaptation/adjusted_mclmc_adaptation.py b/blackjax/adaptation/adjusted_mclmc_adaptation.py index 408c31383..474bfc5cc 100644 --- a/blackjax/adaptation/adjusted_mclmc_adaptation.py +++ b/blackjax/adaptation/adjusted_mclmc_adaptation.py @@ -28,6 +28,7 @@ def adjusted_mclmc_find_L_and_step_size( max="avg", num_windows=1, tuning_factor=1.3, + euclidean=False, ): """ Finds the optimal value of the parameters for the MH-MCHMC algorithm. @@ -73,7 +74,14 @@ def adjusted_mclmc_find_L_and_step_size( dim = pytree_size(state.position) if params is None: - params = MCLMCAdaptationState( + if euclidean: + + params = MCLMCAdaptationState( + 1.0, 0.2, inverse_mass_matrix=jnp.ones((dim,)) + ) + + else: + params = MCLMCAdaptationState( jnp.sqrt(dim), jnp.sqrt(dim) * 0.2, inverse_mass_matrix=jnp.ones((dim,)) ) @@ -96,6 +104,7 @@ def adjusted_mclmc_find_L_and_step_size( diagonal_preconditioning=diagonal_preconditioning, max=max, tuning_factor=tuning_factor, + euclidean=euclidean, )( state, params, num_steps, window_key ) @@ -113,7 +122,7 @@ def adjusted_mclmc_find_L_and_step_size( ) = adjusted_mclmc_make_adaptation_L( mclmc_kernel, frac=frac_tune3, - Lfactor=0.5, + Lfactor=0.3, max=max, eigenvector=eigenvector, )( @@ -156,6 +165,7 @@ def adjusted_mclmc_make_L_step_size_adaptation( fix_L_first_da=False, max="avg", tuning_factor=1.0, + euclidean=False, ): """Adapts the stepsize and L of the MCLMC kernel. Designed for adjusted MCLMC""" @@ -207,6 +217,7 @@ def step(iteration_state, weight_and_key): step_size = jax.lax.clamp( 1e-5, jnp.exp(adaptive_state.log_step_size), params.L / 1.1 ) + # jax.debug.print("step size in adaptation {x}",x=step_size) adaptive_state = adaptive_state._replace(log_step_size=jnp.log(step_size)) x = ravel_pytree(state.position)[0] @@ -256,7 +267,10 @@ def L_step_size_adaptation(state, params, num_steps, rng_key): num_steps * frac_tune2 ) - check_key, rng_key = jax.random.split(rng_key, 2) + # jax.debug.print("num steps1 {x}",x=num_steps1) + # jax.debug.print("num steps 2 {x}",x=num_steps2) + + # check_key, rng_key = jax.random.split(rng_key, 2) rng_key_pass1, rng_key_pass2 = jax.random.split(rng_key, 2) L_step_size_adaptation_keys_pass1 = jax.random.split( @@ -293,24 +307,49 @@ def L_step_size_adaptation(state, params, num_steps, rng_key): variances = x_squared_average - jnp.square(x_average) if max == "max": - contract = lambda x: jnp.sqrt(jnp.max(x) * dim) * tuning_factor + if euclidean: + contract = lambda x: (jnp.sqrt(jnp.max(x) * dim) * tuning_factor) / jnp.sqrt(dim) + + else: + contract = lambda x: jnp.sqrt(jnp.max(x) * dim) * tuning_factor elif max == "avg": - contract = lambda x: jnp.sqrt(jnp.sum(x)) * tuning_factor + print("avg") + if euclidean: + + contract = lambda x: (jnp.sqrt(jnp.sum(x)) * tuning_factor) / jnp.sqrt(dim) + else: + contract = lambda x: jnp.sqrt(jnp.sum(x)) * tuning_factor else: raise ValueError("max should be either 'max' or 'avg'") + new_L = params.L + change = jax.lax.clamp( Lratio_lowerbound, - contract(variances) / params.L, + contract(variances) / new_L, Lratio_upperbound, ) + # if euclidean: + # # new_L /= jnp.sqrt(dim) + # change /= jnp.sqrt(dim) + + params = params._replace( L=params.L * change, step_size=params.step_size * change ) if diagonal_preconditioning: - params = params._replace(inverse_mass_matrix=variances, L=jnp.sqrt(dim)) + if euclidean: + params = params._replace(inverse_mass_matrix=variances, L=1.) + else: + params = params._replace(inverse_mass_matrix=variances, L=jnp.sqrt(dim)) + + # else: + # if euclidean: + # params = params._replace(L = params.L / jnp.sqrt(dim)) + + # jax.debug.print("params L {x}", x=(params.L, contract(variances), jnp.sum(variances), tuning_factor)) initial_da, update_da, final_da = dual_averaging_adaptation(target=target) ( @@ -330,6 +369,7 @@ def L_step_size_adaptation(state, params, num_steps, rng_key): params = params._replace(step_size=final_da(dual_avg_state)) + return state, params, eigenvector, num_tuning_integrator_steps return L_step_size_adaptation diff --git a/blackjax/adaptation/ensemble_mclmc.py b/blackjax/adaptation/ensemble_mclmc.py new file mode 100644 index 000000000..eb15cf908 --- /dev/null +++ b/blackjax/adaptation/ensemble_mclmc.py @@ -0,0 +1,319 @@ +# Copyright 2020- The Blackjax Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# """Public API for the MCLMC Kernel""" + +# import jax +# import jax.numpy as jnp +# from blackjax.util import run_eca +# import blackjax.adaptation.ensemble_umclmc as umclmc + + +from typing import Any, NamedTuple + +import jax +import jax.numpy as jnp + +import blackjax.adaptation.ensemble_umclmc as umclmc +from blackjax.adaptation.ensemble_umclmc import ( + equipartition_diagonal, + equipartition_diagonal_loss, +) +from blackjax.adaptation.step_size import bisection_monotonic_fn +from blackjax.mcmc.adjusted_mclmc import build_kernel as build_kernel_malt +from blackjax.mcmc.hmc import HMCState +from blackjax.mcmc.integrators import ( + generate_isokinetic_integrator, + mclachlan_coefficients, + omelyan_coefficients, +) +from blackjax.util import run_eca + + +class AdaptationState(NamedTuple): + steps_per_sample: float + step_size: float + stepsize_adaptation_state: ( + Any # the state of the bisection algorithm to find a stepsize + ) + iteration: int + + +build_kernel = lambda logdensity_fn, integrator, inverse_mass_matrix: lambda key, state, adap: build_kernel_malt( + # logdensity_fn=logdensity_fn, + integrator=integrator, + L_proposal_factor=1.25, +)( + rng_key=key, + state=state, + logdensity_fn=logdensity_fn, + step_size=adap.step_size, + integration_steps_fn=lambda k:adap.steps_per_sample, + inverse_mass_matrix=inverse_mass_matrix, +) + + +class Adaptation: + def __init__( + self, + adaptation_state, + num_adaptation_samples, # amount of tuning in the adjusted phase before fixing params + steps_per_sample=15, # L/eps + acc_prob_target=0.8, + observables=lambda x: 0.0, # just for diagnostics: some function of a given chain at given timestep + observables_for_bias=lambda x: 0.0, # just for diagnostics: the above, but averaged over all chains + contract=lambda x: 0.0, # just for diagnostics: observables for bias, contracted over dimensions + ): + self.num_adaptation_samples = num_adaptation_samples + self.observables = observables + self.observables_for_bias = observables_for_bias + self.contract = contract + + # Determine the initial hyperparameters # + + # stepsize # + # if we switched to the more accurate integrator we can use longer step size + # integrator_factor = jnp.sqrt(10.) if mclachlan else 1. + # Let's use the stepsize which will be optimal for the adjusted method. The energy variance after N steps scales as sigma^2 ~ N^2 eps^6 = eps^4 L^2 + # In the adjusted method we want sigma^2 = 2 mu = 2 * 0.41 = 0.82 + # With the current eps, we had sigma^2 = EEVPD * d for N = 1. + # Combining the two we have EEVPD * d / 0.82 = eps^6 / eps_new^4 L^2 + # adjustment_factor = jnp.power(0.82 / (ndims * adaptation_state.EEVPD), 0.25) / jnp.sqrt(steps_per_sample) + step_size = adaptation_state.step_size + + # Initialize the bisection for finding the step size + self.epsadap_update = bisection_monotonic_fn(acc_prob_target) + stepsize_adaptation_state = (jnp.array([-jnp.inf, jnp.inf]), False) + + self.initial_state = AdaptationState( + steps_per_sample, step_size, stepsize_adaptation_state, 0 + ) + + def summary_statistics_fn(self, state, info, rng_key): + return { + "acceptance_probability": info.acceptance_rate, + "equipartition_diagonal": equipartition_diagonal(state), + "observables": self.observables(state.position), + "observables_for_bias": self.observables_for_bias(state.position), + } + + def update(self, adaptation_state, Etheta): + acc_prob = Etheta["acceptance_probability"] + equi_diag = equipartition_diagonal_loss(Etheta["equipartition_diagonal"]) + true_bias = self.contract(Etheta["observables_for_bias"]) + + info_to_be_stored = { + "L": adaptation_state.step_size * adaptation_state.steps_per_sample, + "steps_per_sample": adaptation_state.steps_per_sample, + "step_size": adaptation_state.step_size, + "acc_prob": acc_prob, + "equi_diag": equi_diag, + "bias": true_bias, + "observables": Etheta["observables"], + } + + # Bisection to find step size + stepsize_adaptation_state, step_size = self.epsadap_update( + adaptation_state.stepsize_adaptation_state, + adaptation_state.step_size, + acc_prob, + ) + + return ( + AdaptationState( + adaptation_state.steps_per_sample, + step_size, + stepsize_adaptation_state, + adaptation_state.iteration + 1, + ), + info_to_be_stored, + ) + + +def bias(model): + """should be transfered to benchmarks/""" + + def observables(position): + return jnp.square(model.transform(position)) + + def contract(sampler_E_x2): + bsq = jnp.square(sampler_E_x2 - model.E_x2) / model.Var_x2 + return jnp.array([jnp.max(bsq), jnp.average(bsq)]) + + return observables, contract + + +def while_steps_num(cond): + if jnp.all(cond): + return len(cond) + else: + return jnp.argmin(cond) + 1 + + + +def laps( + logdensity_fn, + sample_init, + ndims, + num_steps1, + num_steps2, + num_chains, + mesh, + rng_key, + alpha=1.9, + save_frac=0.2, + C=0.1, + early_stop=True, + r_end= 0.01, + bias_type= 3, + diagonal_preconditioning=True, + integrator_coefficients=None, + steps_per_sample=15, + acc_prob=None, + observables_for_bias=lambda x: x, + ensemble_observables=None, + diagnostics=True, + contract=lambda x: 0.0, + superchain_size= 1, +): + """ + model: the target density object + num_steps1: number of steps in the first phase + num_steps2: number of steps in the second phase + num_chains: number of chains + mesh: the mesh object, used for distributing the computation across cpus and nodes + rng_key: the random key + alpha: L = sqrt{d}*alpha*variances + save_frac: the fraction of samples used to estimate the fluctuation in the first phase + C: constant in stage 1 that determines step size (eq (9) of EMAUS paper) + early_stop: whether to stop the first phase early + r_end + diagonal_preconditioning: whether to use diagonal preconditioning + integrator_coefficients: the coefficients of the integrator + steps_per_sample: the number of steps per sample + acc_prob: the acceptance probability + observables: the observables (for diagnostic use) + ensemble_observables: observable calculated over the ensemble (for diagnostic use) + diagnostics: whether to return diagnostics + """ + + key_init, key_umclmc, key_mclmc = jax.random.split(rng_key, 3) + + # initialize the chains + initial_state = umclmc.initialize( + key_init, logdensity_fn, sample_init, num_chains, mesh, superchain_size + ) + + # burn-in with the unadjusted method # + kernel = umclmc.build_kernel(logdensity_fn) + save_num = (jnp.rint(save_frac * num_steps1)).astype(int) + adap = umclmc.Adaptation( + ndims, + alpha=alpha, + bias_type=bias_type, + save_num=save_num, + C=C, + r_end=r_end, + observables_for_bias=observables_for_bias, + contract=contract, + ) + + final_state, final_adaptation_state, info1, steps_done_phase_1 = run_eca( + key_umclmc, + initial_state, + kernel, + adap, + num_steps1, + num_chains, + mesh, + superchain_size, + ensemble_observables, + early_stop=early_stop, + ) + + # refine the results with the adjusted method + _acc_prob = acc_prob + if integrator_coefficients is None: + high_dims = ndims > 200 + _integrator_coefficients = ( + omelyan_coefficients if high_dims else mclachlan_coefficients + ) + if acc_prob is None: + _acc_prob = 0.9 if high_dims else 0.7 + + else: + _integrator_coefficients = integrator_coefficients + if acc_prob is None: + _acc_prob = 0.9 + + integrator = generate_isokinetic_integrator(_integrator_coefficients) + gradient_calls_per_step = ( + len(_integrator_coefficients) // 2 + ) # scheme = BABAB..AB scheme has len(scheme)//2 + 1 Bs. The last doesn't count because that gradient can be reused in the next step. + + if diagonal_preconditioning: + inverse_mass_matrix = final_adaptation_state.inverse_mass_matrix + + # scale the stepsize so that it reflects averag scale change of the preconditioning + average_scale_change = jnp.sqrt(jnp.average(inverse_mass_matrix)) + final_adaptation_state = final_adaptation_state._replace( + step_size=final_adaptation_state.step_size / average_scale_change + ) + + else: + inverse_mass_matrix = 1.0 + + kernel = build_kernel( + logdensity_fn, integrator, inverse_mass_matrix=inverse_mass_matrix + ) + + initial_state = HMCState( + final_state.position, final_state.logdensity, final_state.logdensity_grad + # jax.random.key(0) + ) + num_samples = num_steps2 // (gradient_calls_per_step * steps_per_sample) + num_adaptation_samples = ( + num_samples // 2 + ) # number of samples after which the stepsize is fixed. + + final_adaptation_state = final_adaptation_state._replace( + step_size=final_adaptation_state.step_size.item() + ) + + adap = Adaptation( + final_adaptation_state, + num_adaptation_samples, + steps_per_sample, + _acc_prob, + contract=contract, + observables_for_bias=observables_for_bias, + ) + + final_state, final_adaptation_state, info2, _ = run_eca( + key_mclmc, + initial_state, + kernel, + adap, + num_samples, + num_chains, + mesh, + superchain_size, + ensemble_observables + ) + + if diagnostics: + info = {"phase_1": info1, "phase_2": info2} + else: + info = None + + return info, gradient_calls_per_step, _acc_prob, final_state diff --git a/blackjax/adaptation/ensemble_umclmc.py b/blackjax/adaptation/ensemble_umclmc.py new file mode 100644 index 000000000..46b3c8346 --- /dev/null +++ b/blackjax/adaptation/ensemble_umclmc.py @@ -0,0 +1,328 @@ +# Copyright 2020- The Blackjax Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# """Public API for the MCLMC Kernel""" + +from typing import Any, NamedTuple + +import jax +import jax.numpy as jnp +from jax.flatten_util import ravel_pytree + +from blackjax.mcmc import mclmc +from blackjax.mcmc.integrators import ( + IntegratorState, + _normalized_flatten_array, + isokinetic_velocity_verlet, +) +from blackjax.types import Array +from blackjax.util import ensemble_execute_fn + + +def no_nans(a): + flat_a, unravel_fn = ravel_pytree(a) + return jnp.all(jnp.isfinite(flat_a)) + + +def nan_reject(nonans, old, new): + """Equivalent to + return new if nonans else old""" + + return jax.lax.cond(nonans, lambda _: new, lambda _: old, operand=None) + + +def build_kernel(logdensity_fn): + """MCLMC kernel (with nan rejection)""" + + # kernel = mclmc.build_kernel( + # logdensity_fn=logdensity_fn, integrator=isokinetic_velocity_verlet + # ) + + def sequential_kernel(key, state, adap): + new_state, info = mclmc.build_kernel( + integrator=isokinetic_velocity_verlet, + )(key, state,logdensity_fn, adap.L, adap.step_size,jnp.ones(adap.inverse_mass_matrix.shape)) + + # reject the new state if there were nans + nonans = no_nans(new_state) + new_state = nan_reject(nonans, state, new_state) + + return new_state, { + "nans": 1 - nonans, + "energy_change": info.energy_change * nonans, + "logdensity": info.logdensity * nonans, + } + + return sequential_kernel + + +def initialize(rng_key, logdensity_fn, sample_init, num_chains, mesh, superchain_size): + """initialize the chains based on the equipartition of the initial condition. + We initialize the velocity along grad log p if E_ii > 1 and along -grad log p if E_ii < 1. + """ + + def sequential_init(key, x, args): + """initialize the position using sample_init and the velocity along the gradient""" + position = sample_init(key) + + logdensity, logdensity_grad = jax.value_and_grad(logdensity_fn)(position) + flat_g, unravel_fn = ravel_pytree(logdensity_grad) + velocity = unravel_fn( + _normalized_flatten_array(flat_g)[0] + ) # = grad logp/ |grad logp| + + return IntegratorState(position, velocity, logdensity, logdensity_grad), None + + def summary_statistics_fn(state): + """compute the diagonal elements of the equipartition matrix""" + flat_pos, unflatten = jax.flatten_util.ravel_pytree(state.position) + flat_g, unravel_fn = ravel_pytree(state.logdensity_grad) + return unravel_fn(-flat_pos * flat_g) + # return 0 + + # -state.position # * state.logdensity_grad + + def ensemble_init(key, state, signs): + """flip the velocity, depending on the equipartition condition""" + + momentum, unflatten = jax.flatten_util.ravel_pytree(state.momentum) + + velocity_flat = jax.tree_util.tree_map( + lambda sign, u: sign * u, signs, momentum + ) + + velocity = unflatten(velocity_flat) + + return ( + IntegratorState( + state.position, velocity, state.logdensity, state.logdensity_grad + ), + None, + ) + + key1, key2 = jax.random.split(rng_key) + initial_state, equipartition = ensemble_execute_fn( + sequential_init, + key1, + num_chains, + mesh, + summary_statistics_fn=summary_statistics_fn, + superchain_size= superchain_size + ) + + flat_equi, _ = ravel_pytree(equipartition) + + signs = -2.0 * (flat_equi < 1.0) + 1.0 + initial_state, _ = ensemble_execute_fn(ensemble_init, key2, num_chains, mesh, x=initial_state, args=signs, superchain_size= superchain_size) + + return initial_state + + +def update_history(new_vals, history): + new_vals, _ = jax.flatten_util.ravel_pytree(new_vals) + return jnp.concatenate((new_vals[None, :], history[:-1, :])) + + +def update_history_scalar(new_val, history): + return jnp.concatenate((new_val * jnp.ones(1), history[:-1])) + + +def contract_history(theta, weights): + square_average = jnp.square(jnp.average(theta, weights=weights, axis=0)) + average_square = jnp.average(jnp.square(theta), weights=weights, axis=0) + + r = (average_square - square_average) / square_average + + return jnp.array([jnp.max(r), jnp.average(r)]) + + +class History(NamedTuple): + observables: Array + stopping: Array + weights: Array + + +class AdaptationState(NamedTuple): + L: float + inverse_mass_matrix: Any + step_size: float + + step_count: int + EEVPD: float + EEVPD_wanted: float + history: Any + + +def equipartition_diagonal(state): + """Ei = E_ensemble (- grad log p_i x_i ). Ei is 1 if we have converged. + equipartition_loss = average over parameters (Ei)""" + return jax.tree_util.tree_map( + lambda x, g: -x * g, state.position, state.logdensity_grad + ) + + +def equipartition_fullrank(state, rng_key): + """loss = Tr[(1 - E)^T (1 - E)] / d^2 + where Eij = is the equipartition patrix. + Loss is computed with the Hutchinson's trick.""" + + x, unravel_fn = ravel_pytree(state.position) + g, unravel_fn = ravel_pytree(state.logdensity_grad) + d = len(x) + + def func(z): + """z here has the same shape as position""" + return z + jnp.dot(z, g) * x + + z = jax.random.rademacher(rng_key, (100, d)) # = delta_ij + return jax.vmap(func)(z) + + +def equipartition_diagonal_loss(Eii): + Eii_flat, unravel_fn = ravel_pytree(Eii) + return jnp.average(jnp.square(1.0 - Eii_flat)) + + +def equipartition_fullrank_loss(delta_z): + d = delta_z.shape[-1] + return jnp.average(jnp.square(delta_z)) / d + + +class Adaptation: + def __init__( + self, + ndims, + alpha=1.0, + C=0.1, + r_end=0.01, + bias_type=0, + save_num=10, + observables=lambda x: 0.0, + observables_for_bias=lambda x: x, + contract=lambda x: 0.0, + ): + self.ndims = ndims + self.alpha = alpha + self.C = C + self.r_end = r_end + self.observables = observables + self.observables_for_bias = observables_for_bias + self.contract = contract + self.bias_type = bias_type + self.save_num = save_num + r_save_num = save_num + + history = History( + observables=jnp.zeros((r_save_num, ndims)), + stopping=jnp.full((save_num,), jnp.nan), + weights=jnp.zeros(r_save_num), + ) + + self.initial_state = AdaptationState( + L=jnp.inf, # do not add noise for the first step + inverse_mass_matrix=jnp.ones(ndims), + step_size=0.01 * jnp.sqrt(ndims), + step_count=0, + EEVPD=1e-3, + EEVPD_wanted=1e-3, + history=history, + ) + + # info 1 + def summary_statistics_fn(self, state, info, rng_key): + position_flat, unravel_fn = ravel_pytree(state.position) + + return { + "equipartition_diagonal": equipartition_diagonal(state), + "equipartition_fullrank": equipartition_fullrank(state, rng_key), + "x": position_flat, + "xsq": jnp.square(position_flat), + "E": info["energy_change"], + "Esq": jnp.square(info["energy_change"]), + "rejection_rate_nans": info["nans"], + "observables_for_bias": self.observables_for_bias(state.position), + "observables": self.observables(state.position), + "entropy": -info["logdensity"], + "uturn": jnp.sqrt(jnp.sum(jnp.square(state.logdensity_grad - jnp.dot(state.logdensity_grad, state.momentum) * state.momentum))) / (self.ndims - 1) + } + + def update(self, adaptation_state, Etheta): + # combine the expectation values to get useful scalars + equi_diag = equipartition_diagonal_loss(Etheta["equipartition_diagonal"]) + equi_full = equipartition_fullrank_loss(Etheta["equipartition_fullrank"]) + + history_observables = update_history( + Etheta["observables_for_bias"], adaptation_state.history.observables + ) + + history_weights = update_history_scalar(1.0, adaptation_state.history.weights) + fluctuations = contract_history(history_observables, history_weights) + history_stopping = update_history_scalar( + jax.lax.cond( + adaptation_state.step_count > len(history_weights), + lambda _: fluctuations[0], + lambda _: jnp.nan, + operand=None, + ), + adaptation_state.history.stopping, + ) + history = History(history_observables, history_stopping, history_weights) + + L = self.alpha * jnp.sqrt(jnp.sum(Etheta["xsq"] - jnp.square(Etheta["x"]))) # average over the ensemble, sum over parameters (to get sqrt(d)) + #L = self.alpha / Etheta["uturn"] + inverse_mass_matrix = Etheta["xsq"] - jnp.square(Etheta["x"]) + EEVPD = (Etheta["Esq"] - jnp.square(Etheta["E"])) / self.ndims + true_bias = self.contract(Etheta["observables_for_bias"]) + nans = Etheta["rejection_rate_nans"] > 0.0 # | (~jnp.isfinite(eps_factor)) + + # hyperparameter adaptation + # estimate bias + bias = jnp.array([fluctuations[0], fluctuations[1], equi_full, equi_diag])[self.bias_type] # r_max, r_avg, equi_full, equi_diag + EEVPD_wanted = self.C * jnp.power(bias, 3./8.) + # bias_asym_wanted = self.C * bias + # EEVPD_wanted = 4 * jnp.power(bias_asym_wanted, 3./2.) / jnp.square(1 + jnp.sqrt(bias_asym_wanted)) # phi function from Robnik et. al., Blackbox Unadjusted Hamiltonian Monte Carlo + + eps_factor = jnp.power(EEVPD_wanted / EEVPD, 1.0 / 6.0) + eps_factor = jnp.clip(eps_factor, 0.3, 3.0) + + eps_factor = nan_reject(1 - nans, 0.5, eps_factor) # reduce the stepsize if there were nans + + info_to_be_stored = { + "L": adaptation_state.L, + "step_size": adaptation_state.step_size, + "EEVPD_wanted": EEVPD_wanted, + "EEVPD": EEVPD, + "equi_diag": equi_diag, + "equi_full": equi_full, + "bias": true_bias, + "r_max": fluctuations[0], + "r_avg": fluctuations[1], + "entropy": Etheta["entropy"], + "observables": Etheta["observables"], + } + + adaptation_state_new = AdaptationState( + L, + inverse_mass_matrix, + adaptation_state.step_size * eps_factor, + adaptation_state.step_count + 1, + EEVPD, + EEVPD_wanted, + history, + ) + + return adaptation_state_new, info_to_be_stored + + def while_cond(self, info): + """determine if we want to switch to adjustment""" + return info['r_max'] > self.r_end \ No newline at end of file diff --git a/blackjax/adaptation/las.py b/blackjax/adaptation/las.py new file mode 100644 index 000000000..f4c975411 --- /dev/null +++ b/blackjax/adaptation/las.py @@ -0,0 +1,152 @@ +import jax +import jax.numpy as jnp +import blackjax +from blackjax.util import run_inference_algorithm +import blackjax + +from blackjax.adaptation.unadjusted_alba import unadjusted_alba +from blackjax.adaptation.unadjusted_step_size import robnik_step_size_tuning +from blackjax.adaptation.unadjusted_alba import unadjusted_alba +import math +from blackjax.mcmc.adjusted_mclmc_dynamic import make_random_trajectory_length_fn +from functools import partial +from blackjax.adaptation.step_size import bisection_monotonic_fn + +# unbelievable that this is not in the standard library +def compose(f, g): + return lambda x: f(g(x)) + + +def las(logdensity_fn, num_chains, key, ndims, num_adjusted_steps, diagonal_preconditioning=True, target_acceptance_rate=0.8): + + init_key, tune_key, unadjusted_key, adjusted_key = jax.random.split(key, 4) + initial_position = jax.random.normal(init_key, (ndims,)) + + ### Phase 1: unadjusted ### + + integrator = blackjax.mcmc.integrators.isokinetic_mclachlan + + # burn-in and adaptation + num_alba_steps = 10000 + warmup = unadjusted_alba( + algorithm=blackjax.mclmc, + logdensity_fn=logdensity_fn, integrator=integrator, + target_eevpd=5e-4, + # target_acceptance_rate=target_acceptance_rate, + v=jnp.sqrt(ndims), + num_alba_steps=num_alba_steps, + preconditioning=diagonal_preconditioning, + alba_factor=0.4, + ) + + (blackjax_state_after_tuning, blackjax_mclmc_sampler_params), adaptation_info = warmup.run(tune_key, initial_position, 20000) + + # sampling + ess_per_sample = blackjax_mclmc_sampler_params['ESS'] + + num_steps = math.ceil(num_chains // ess_per_sample) + + alg = blackjax.mclmc( + logdensity_fn=logdensity_fn, + L=blackjax_mclmc_sampler_params['L'], + step_size=blackjax_mclmc_sampler_params['step_size'], + inverse_mass_matrix=blackjax_mclmc_sampler_params['inverse_mass_matrix'], + integrator=integrator, + ) + + final_output, history = run_inference_algorithm( + rng_key=unadjusted_key, + initial_state=blackjax_state_after_tuning, + inference_algorithm=alg, + num_steps=num_steps, + transform=(lambda a, b: a), + progress_bar=False, + ) + samples = history.position + + + ### Phase 2: adjusted ### + + subsamples = samples[::math.ceil(1/ess_per_sample)] + + integration_steps_fn = make_random_trajectory_length_fn(True) + + + # initial_states = jax.lax.map(lambda x: blackjax.adjusted_mclmc_dynamic.init(x, logdensity_fn, jax.random.key(0)), xs=subsamples) + # initial_states = jax.lax.map(lambda x: blackjax.adjusted_mclmc_dynamic.init(x, logdensity_fn, jax.random.key(0)), xs=subsamples) + + def make_mams_step(key): + def mams_step(inp): + # init_key, run_key = jax.random.split(key, 2) + + step_size, positions, info, step_size_adaptation_state = inp + keys = jax.random.split(key, positions.shape[0]) + # num_steps_per_traj = blackjax_mclmc_sampler_params['L'] / step_size + num_steps_per_traj = 1 + + alg = blackjax.adjusted_mclmc_dynamic( + logdensity_fn=logdensity_fn, + step_size=step_size, + integration_steps_fn=integration_steps_fn(num_steps_per_traj), + integrator=blackjax.mcmc.integrators.isokinetic_velocity_verlet, + inverse_mass_matrix=blackjax_mclmc_sampler_params['inverse_mass_matrix'], + L_proposal_factor=jnp.inf, + ) + + # run_keys = jax.random.split(run_key, positions.shape[0]) + + def step_fn(pos_key): + pos, key = pos_key + init_key, run_key = jax.random.split(key, 2) + return alg.step( + rng_key=run_key, + state=blackjax.adjusted_mclmc_dynamic.init(pos, logdensity_fn, init_key), + ) + + new_states, infos = jax.lax.map(step_fn, xs=(positions,keys)) + # jax.debug.print("infos adaptation step: {infos}", infos=jnp.sum(infos.is_accepted)) + return (step_size, new_states.position, infos, step_size_adaptation_state) + + return mams_step + + epsadap_update = bisection_monotonic_fn(target_acceptance_rate) + step_size_adaptation_state_initial = (jnp.array([-jnp.inf, jnp.inf]), False) + + def tuning_step(inp): + + old_step_size, old_positions, old_infos, step_size_adaptation_state = inp + acc_rate = old_infos.acceptance_rate.mean() + + + step_size_adaptation_state, new_step_size = epsadap_update( + step_size_adaptation_state, + old_step_size, + acc_rate, + ) + + return (new_step_size, old_positions, old_infos, step_size_adaptation_state) + # return (10.0, old_positions, old_infos, step_size_adaptation_state) + + step = lambda key: compose(tuning_step, make_mams_step(key)) + + initial_adjusted_key, adjusted_key = jax.random.split(adjusted_key, 2) + _, _, infos, _ = make_mams_step(initial_adjusted_key)((blackjax_mclmc_sampler_params['step_size'], subsamples, None, step_size_adaptation_state_initial)) + + + positions = subsamples + step_size = blackjax_mclmc_sampler_params['step_size'] + + (step_size, position, infos, step_size_adaptation_state), (step_sizes, positions, infos, step_size_adaptation_state) = jax.lax.scan(lambda state, key: (step(key)(state), step(key)(state)), (step_size, subsamples, infos, step_size_adaptation_state_initial), jax.random.split(adjusted_key, num_adjusted_steps)) + + return samples, positions, infos, num_steps, step_size_adaptation_state + +# type: forall a, b: (a -> b) -> (b -> a) -> Int -> (a -> b) +# e.g.: a ~ (stepsize, position), b ~ (state) +def feedback(f,g, n, state_a): + for i in range(n): + state_b = f(state_a) + # print(state_b, "state_b") + state_a = g(state_b) + # print(state_a, "state_a") + return state_a + diff --git a/blackjax/adaptation/mass_matrix.py b/blackjax/adaptation/mass_matrix.py index dc0730161..bb74fa2ee 100644 --- a/blackjax/adaptation/mass_matrix.py +++ b/blackjax/adaptation/mass_matrix.py @@ -132,7 +132,7 @@ def final(mm_state: MassMatrixAdaptationState) -> MassMatrixAdaptationState: """Final iteration of the mass matrix adaptation. In this step we compute the mass matrix from the covariance matrix computed - by the Welford algorithm, and re-initialize the later. + by the Welford algorithm, and re-initialize the latter. """ _, wc_state = mm_state diff --git a/blackjax/adaptation/mclmc_adaptation.py b/blackjax/adaptation/mclmc_adaptation.py index fa644898a..e5c1c900f 100644 --- a/blackjax/adaptation/mclmc_adaptation.py +++ b/blackjax/adaptation/mclmc_adaptation.py @@ -21,6 +21,7 @@ from blackjax.diagnostics import effective_sample_size from blackjax.util import generate_unit_vector, incremental_value_update, pytree_size +import blackjax.mcmc.metrics as metrics class MCLMCAdaptationState(NamedTuple): @@ -50,8 +51,10 @@ def mclmc_find_L_and_step_size( desired_energy_var=5e-4, trust_in_estimate=1.5, num_effective_samples=150, - diagonal_preconditioning=True, params=None, + diagonal_preconditioning=True, + num_windows=1, + euclidean=False ): """ Finds the optimal value of the parameters for the MCLMC algorithm. @@ -72,7 +75,7 @@ def mclmc_find_L_and_step_size( The fraction of tuning for the second step of the adaptation. frac_tune3 The fraction of tuning for the third step of the adaptation. - desired_energy_va + desired_energy_var The desired energy variance for the MCMC algorithm. trust_in_estimate The trust in the estimate of optimal stepsize. @@ -82,6 +85,7 @@ def mclmc_find_L_and_step_size( Whether to do diagonal preconditioning (i.e. a mass matrix) params Initial params to start tuning from (optional) + euclidean: if this tuning is used for HMC or underdamped LMC, there are sqrt{d} factors that need to be taken into account (because L is parametrized differently) Returns ------- @@ -109,9 +113,18 @@ def mclmc_find_L_and_step_size( """ dim = pytree_size(state.position) if params is None: - params = MCLMCAdaptationState( - jnp.sqrt(dim), jnp.sqrt(dim) * 0.25, inverse_mass_matrix=jnp.ones((dim,)) - ) + if euclidean: + params = MCLMCAdaptationState( + 1, 0.25, inverse_mass_matrix=jnp.ones((dim,)) + ) + else: + params = MCLMCAdaptationState( + jnp.sqrt(dim), jnp.sqrt(dim) * 0.25, inverse_mass_matrix=jnp.ones((dim,)) + ) + + + # jax.debug.print("params {x}", x=(params, euclidean)) + part1_key, part2_key = jax.random.split(rng_key, 2) total_num_tuning_integrator_steps = 0 @@ -122,16 +135,21 @@ def mclmc_find_L_and_step_size( num_steps2 += diagonal_preconditioning * (num_steps2 // 3) num_steps3 = round(num_steps * frac_tune3) - state, params = make_L_step_size_adaptation( - kernel=mclmc_kernel, - dim=dim, - frac_tune1=frac_tune1, - frac_tune2=frac_tune2, - desired_energy_var=desired_energy_var, - trust_in_estimate=trust_in_estimate, - num_effective_samples=num_effective_samples, - diagonal_preconditioning=diagonal_preconditioning, - )(state, params, num_steps, part1_key) + for i in range(num_windows): + window_key = jax.random.fold_in(part1_key, i) + + state, params = make_L_step_size_adaptation( + kernel=mclmc_kernel, + dim=dim, + frac_tune1=frac_tune1/num_windows, + frac_tune2=frac_tune2/num_windows, + desired_energy_var=desired_energy_var, + trust_in_estimate=trust_in_estimate, + num_effective_samples=num_effective_samples, + diagonal_preconditioning=diagonal_preconditioning, + euclidean=euclidean + )(state, params, num_steps, window_key) + total_num_tuning_integrator_steps += num_steps1 + num_steps2 if num_steps3 >= 2: # at least 2 samples for ESS estimation @@ -152,6 +170,7 @@ def make_L_step_size_adaptation( desired_energy_var=1e-3, trust_in_estimate=1.5, num_effective_samples=150, + euclidean=False ): """Adapts the stepsize and L of the MCLMC kernel. Designed for unadjusted MCLMC""" @@ -163,7 +182,7 @@ def predictor(previous_state, params, adaptive_state, rng_key): time, x_average, step_size_max = adaptive_state - rng_key, nan_key = jax.random.split(rng_key) + rng_key, nan_key, energy_key = jax.random.split(rng_key, 3) # dynamics next_state, info = kernel(params.inverse_mass_matrix)( @@ -173,6 +192,26 @@ def predictor(previous_state, params, adaptive_state, rng_key): step_size=params.step_size, ) + ndims = pytree_size(previous_state.position) + cutoff = jnp.sqrt(ndims * desired_energy_var * 10**4) + energy_change_, next_state = handle_high_energy( + next_state=next_state, + previous_state=previous_state, + energy_change=info.energy_change, + key=energy_key, + inverse_mass_matrix=params.inverse_mass_matrix, + euclidean=euclidean, + cutoff=cutoff + ) + + info = info._replace( + energy_change=energy_change_, + ) + + # jax.debug.print("info.energy_change {x}", x=info.energy_change) + + + # step updating success, state, step_size_max, energy_change = handle_nans( previous_state, @@ -181,8 +220,15 @@ def predictor(previous_state, params, adaptive_state, rng_key): step_size_max, info.energy_change, nan_key, + euclidean=euclidean, ) + # energy_change = jnp.clip( + # energy_change, + # -25, + # 25 + # ) + # Warning: var = 0 if there were nans, but we will give it a very small weight xi = ( jnp.square(energy_change) / (dim * desired_energy_var) @@ -190,10 +236,15 @@ def predictor(previous_state, params, adaptive_state, rng_key): weight = jnp.exp( -0.5 * jnp.square(jnp.log(xi) / (6.0 * trust_in_estimate)) ) # the weight reduces the impact of stepsizes which are much larger on much smaller than the desired one. + # jax.debug.print("energy change {x}", x=energy_change) + # jax.debug.print("step size {x}", x=params.step_size) + x_average = decay_rate * x_average + weight * ( xi / jnp.power(params.step_size, 6.0) ) + # jax.debug.print("xi {x}", x=(xi, energy_change, x_average)) + time = decay_rate * time + weight step_size = jnp.power( x_average / time, -1.0 / 6.0 @@ -201,6 +252,12 @@ def predictor(previous_state, params, adaptive_state, rng_key): step_size = (step_size < step_size_max) * step_size + ( step_size > step_size_max ) * step_size_max # if the proposed stepsize is above the stepsize where we have seen divergences + + # jax.debug.print("step size {x}", x=(step_size, step_size_max)) + + + + # params_new = params._replace(step_size=(energy_change==0)*params.step_size/2 + (energy_change != 0)*step_size) params_new = params._replace(step_size=step_size) adaptive_state = (time, x_average, step_size_max) @@ -255,22 +312,30 @@ def L_step_size_adaptation(state, params, num_steps, rng_key): mask = jnp.concatenate((jnp.zeros(num_steps1), jnp.ones(num_steps2))) # run the steps - state, params, _, (_, average) = run_steps( + state, params, (_,x_average, _), (_, average) = run_steps( xs=(mask, L_step_size_adaptation_keys), state=state, params=params ) + # jax.debug.print("step size {x}", x=(params.step_size, x_average)) + L = params.L # determine L inverse_mass_matrix = params.inverse_mass_matrix if num_steps2 > 1: x_average, x_squared_average = average[0], average[1] variances = x_squared_average - jnp.square(x_average) - L = jnp.sqrt(jnp.sum(variances)) + L = jnp.sqrt(jnp.sum(variances)) # lmc: should be jnp.mean + if euclidean: + L /= jnp.sqrt(dim) + # jax.debug.print("foo {x}", x=(L, euclidean, variances)) if diagonal_preconditioning: + # jax.debug.print("bar") inverse_mass_matrix = variances params = params._replace(inverse_mass_matrix=inverse_mass_matrix) - L = jnp.sqrt(dim) + L = jnp.sqrt(dim) # lmc: 1 + if euclidean: + L /= jnp.sqrt(dim) # readjust the stepsize steps = round(num_steps2 / 3) # we do some small number of steps @@ -279,6 +344,8 @@ def L_step_size_adaptation(state, params, num_steps, rng_key): xs=(jnp.ones(steps), keys), state=state, params=params ) + # jax.debug.print("params {x}", x=(MCLMCAdaptationState(L, params.step_size, inverse_mass_matrix), euclidean)) + return state, MCLMCAdaptationState(L, params.step_size, inverse_mass_matrix) return L_step_size_adaptation @@ -318,7 +385,7 @@ def step(state, key): def handle_nans( - previous_state, next_state, step_size, step_size_max, kinetic_change, key + previous_state, next_state, step_size, step_size_max, kinetic_change, key, euclidean=False ): """if there are nans, let's reduce the stepsize, and not update the state. The function returns the old state in this case.""" @@ -333,12 +400,42 @@ def handle_nans( (previous_state, step_size * reduced_step_size, 0.0), ) + # new_momentum = euclidean*0.0 + (1-euclidean)*generate_unit_vector(key, previous_state.position) + new_momentum = generate_unit_vector(key, previous_state.position) + + # new_momentum = euclidean*metric.sample_momentum(key, previous_state.position) + (1-euclidean)*generate_unit_vector(key, previous_state.position) + state = jax.lax.cond( jnp.isnan(next_state.logdensity), lambda: state._replace( - momentum=generate_unit_vector(key, previous_state.position) + # momentum=generate_unit_vector(key, previous_state.position) + momentum=new_momentum ), lambda: state, ) return nonans, state, step_size, kinetic_change + + +def handle_high_energy( + previous_state, next_state, energy_change, key, inverse_mass_matrix, cutoff, euclidean=False +): + + + metric = metrics.default_metric(inverse_mass_matrix) + + + new_momentum = euclidean*metric.sample_momentum(key, previous_state.position) + (1-euclidean)*generate_unit_vector(key, previous_state.position) + # new_momentum = generate_unit_vector(key, previous_state.position) + + state = jax.lax.cond( + jnp.abs(energy_change) > cutoff, + lambda: previous_state._replace( + # momentum=generate_unit_vector(key, next_state.position) + momentum=new_momentum + ), + lambda: next_state, + ) + energy_change = jnp.clip(energy_change, -cutoff, cutoff) + + return energy_change, state diff --git a/blackjax/adaptation/step_size.py b/blackjax/adaptation/step_size.py index 2b06172c0..da036c266 100644 --- a/blackjax/adaptation/step_size.py +++ b/blackjax/adaptation/step_size.py @@ -257,3 +257,47 @@ def update(rss_state: ReasonableStepSizeState) -> ReasonableStepSizeState: rss_state = jax.lax.while_loop(do_continue, update, rss_state) return rss_state.step_size + + +def bisection_monotonic_fn(acc_prob_wanted, reduce_shift=jnp.log(2.0), tolerance=0.03): + """Bisection of a monotonically decreassing function, that doesn't require an initially bracketing interval.""" + + def update(state, exp_x, acc_rate_new): + bounds, terminated = state + + # update the bounds + acc_high = acc_rate_new > acc_prob_wanted + x = jnp.log(exp_x) + + def on_true(bounds): + lower, upper = bounds + lower = jnp.max(jnp.array([lower, x])) + return jnp.array([lower, upper]), lower + reduce_shift + + def on_false(bounds): + lower, upper = bounds + upper = jnp.min(jnp.array([upper, x])) + return jnp.array([lower, upper]), upper - reduce_shift + + bounds_new, x_new = jax.lax.cond(acc_high, on_true, on_false, bounds) + + # if we have already found a bracketing interval, do bisection, otherwise further reduce or increase the bounds + bracketing = jnp.all(jnp.isfinite(bounds_new)) + + def reduce(bounds): + return x_new + + def bisect(bounds): + return jnp.average(bounds) + + x_new = jax.lax.cond(bracketing, bisect, reduce, bounds_new) + + stepsize = terminated * exp_x + (1 - terminated) * jnp.exp(x_new) + + terminated_new = ( + jnp.abs(acc_rate_new - acc_prob_wanted) < tolerance + ) | terminated + + return (bounds_new, terminated_new), stepsize + + return update diff --git a/blackjax/adaptation/unadjusted_alba.py b/blackjax/adaptation/unadjusted_alba.py new file mode 100644 index 000000000..9164ee562 --- /dev/null +++ b/blackjax/adaptation/unadjusted_alba.py @@ -0,0 +1,346 @@ +import jax +import jax.numpy as jnp + +from typing import Callable, NamedTuple + +import blackjax.mcmc as mcmc +from blackjax.adaptation.base import AdaptationResults, return_all_adapt_info +from blackjax.adaptation.mass_matrix import ( + MassMatrixAdaptationState, + mass_matrix_adaptation, +) +from blackjax.base import AdaptationAlgorithm +from blackjax.progress_bar import gen_scan_fn +from blackjax.types import Array, ArrayLikeTree, PRNGKey +from blackjax.util import pytree_size +from blackjax.adaptation.window_adaptation import build_schedule +from jax.flatten_util import ravel_pytree +from blackjax.diagnostics import effective_sample_size +from blackjax.adaptation.unadjusted_step_size import robnik_step_size_tuning, RobnikStepSizeTuningState +import math + +class AlbaAdaptationState(NamedTuple): + ss_state: RobnikStepSizeTuningState # step size + imm_state: MassMatrixAdaptationState # inverse mass matrix + step_size: float + inverse_mass_matrix: Array + L : float + +def base( + is_mass_matrix_diagonal: bool, + v, + target_eevpd, + preconditioning: bool = True, +) -> tuple[Callable, Callable, Callable]: + + mm_init, mm_update, mm_final = mass_matrix_adaptation(is_mass_matrix_diagonal) + if not preconditioning: + + mm_update = lambda x, y: x + + mm_final = lambda x: x + + # step_size_init, step_size_update, step_size_final = dual_averaging_adaptation(target_eevpd) + step_size_init, step_size_update, step_size_final = robnik_step_size_tuning(desired_energy_var=target_eevpd) + + def init( + position: ArrayLikeTree, + ) -> AlbaAdaptationState: + + num_dimensions = pytree_size(position) + imm_state = mm_init(num_dimensions) + + ss_state = step_size_init(initial_step_size=jnp.sqrt(num_dimensions)/5, num_dimensions=num_dimensions) + + return AlbaAdaptationState( + ss_state, + imm_state, + ss_state.step_size, + imm_state.inverse_mass_matrix, + L = jnp.sqrt(num_dimensions)/v + ) + + def fast_update( + position: ArrayLikeTree, + info, + warmup_state: AlbaAdaptationState, + ) -> AlbaAdaptationState: + """Update the adaptation state when in a "fast" window. + + Only the step size is adapted in fast windows. "Fast" refers to the fact + that the optimization algorithms are relatively fast to converge + compared to the covariance estimation with Welford's algorithm + + """ + + del position + + + new_ss_state = step_size_update(warmup_state.ss_state, info) + new_step_size = new_ss_state.step_size # jnp.exp(new_ss_state.log_step_size) + + new_inverse_mass_matrix = jax.lax.cond( + preconditioning, + lambda: warmup_state.inverse_mass_matrix, + lambda: jnp.ones_like(warmup_state.inverse_mass_matrix), + ) + + return AlbaAdaptationState( + new_ss_state, + warmup_state.imm_state, + new_step_size, + new_inverse_mass_matrix, + L = warmup_state.L + ) + + def slow_update( + position: ArrayLikeTree, + info, + warmup_state: AlbaAdaptationState, + ) -> AlbaAdaptationState: + + # raise Exception + + new_imm_state = mm_update(warmup_state.imm_state, position) + # jax.debug.print("imm state {x}", x=new_imm_state.inverse_mass_matrix[:3]) + # jax.debug.print("warmup_state.ss_state: {x}", x=(warmup_state.ss_state.step_size)) + new_ss_state = step_size_update(warmup_state.ss_state, info) + # new_ss_state = warmup_state.ss_state + # jax.debug.print("old then new: {new_ss_state}", new_ss_state=(warmup_state.ss_state.step_size, new_ss_state.step_size)) + new_step_size = new_ss_state.step_size # jnp.exp(new_ss_state.log_step_size) + + new_inverse_mass_matrix = jax.lax.cond( + preconditioning, + lambda: warmup_state.inverse_mass_matrix, + lambda: jnp.ones_like(warmup_state.inverse_mass_matrix), + ) + + return AlbaAdaptationState( + new_ss_state, new_imm_state, new_step_size, new_inverse_mass_matrix, L = warmup_state.L + ) + + def slow_final(warmup_state: AlbaAdaptationState) -> AlbaAdaptationState: + + new_imm_state = mm_final(warmup_state.imm_state) + new_ss_state = warmup_state.ss_state + # ._replace(step_size=step_size_final(warmup_state.ss_state)) + # step_size_init(step_size_final(warmup_state.ss_state), warmup_state.ss_state.num_dimensions) + new_step_size = new_ss_state.step_size # jnp.exp(new_ss_state.log_step_size) + # jax.debug.print("new_ss_state: {new_ss_state}", new_ss_state=(new_ss_state.step_size)) + + new_L = jax.lax.cond( + preconditioning, + lambda: jnp.sqrt(warmup_state.ss_state.num_dimensions)/v, + lambda: jnp.sqrt(jnp.sum(new_imm_state.inverse_mass_matrix)), + ) + + # jax.debug.print("new_L: {x}", x=(warmup_state.L, new_L)) + + return AlbaAdaptationState( + new_ss_state, + new_imm_state, + new_step_size, + new_imm_state.inverse_mass_matrix, + L = new_L + ) + + def update( + adaptation_state: AlbaAdaptationState, + adaptation_stage: tuple, + position: ArrayLikeTree, + info, + ) -> AlbaAdaptationState: + """Update the adaptation state and parameter values. + + Parameters + ---------- + adaptation_state + Current adptation state. + adaptation_stage + The current stage of the warmup: whether this is a slow window, + a fast window and if we are at the last step of a slow window. + position + Current value of the model parameters. + value + Value of the acceptance rate for the last mcmc step. + + Returns + ------- + The updated adaptation state. + + """ + stage, is_middle_window_end = adaptation_stage + + warmup_state = jax.lax.switch( + stage, + (fast_update, slow_update), + position, + info, + adaptation_state, + ) + + warmup_state = jax.lax.cond( + is_middle_window_end, + slow_final, + lambda x: x, + warmup_state, + ) + + return warmup_state + + def final(warmup_state: AlbaAdaptationState) -> tuple[float, Array]: + """Return the final values for the step size and mass matrix.""" + step_size = step_size_final(warmup_state.ss_state) + # step_size = jnp.exp(warmup_state.ss_state.log_step_size_avg) + inverse_mass_matrix = warmup_state.imm_state.inverse_mass_matrix + L = warmup_state.L + return step_size, L, inverse_mass_matrix + + return init, update, final + +def unadjusted_alba( + algorithm, + logdensity_fn: Callable, + target_eevpd, + v, + preconditioning: bool = True, + is_mass_matrix_diagonal: bool = True, + progress_bar: bool = False, + adaptation_info_fn: Callable = lambda x, y, z : None, + integrator=mcmc.integrators.velocity_verlet, + num_alba_steps: int = 500, + alba_factor: float = 0.4, + **extra_parameters, +) -> AdaptationAlgorithm: + + + mcmc_kernel = algorithm.build_kernel(integrator) + + adapt_init, adapt_step, adapt_final = base( + is_mass_matrix_diagonal=is_mass_matrix_diagonal, + target_eevpd=target_eevpd, + v=v, + preconditioning=preconditioning + ) + + def one_step(carry, xs): + _, rng_key, adaptation_stage = xs + state, adaptation_state = carry + + new_state, info = mcmc_kernel( + rng_key=rng_key, + state=state, + logdensity_fn=logdensity_fn, + step_size=adaptation_state.step_size, + inverse_mass_matrix=adaptation_state.inverse_mass_matrix, + L=adaptation_state.L, + **extra_parameters, + ) + new_adaptation_state = adapt_step( + adaptation_state, + adaptation_stage, + new_state.position, + info, + ) + # jax.debug.print("info: {x}", x=(new_adaptation_state.step_size, info.energy_change)) + # jax.debug.print("step sizes: {x}", x=(adaptation_state.step_size, new_adaptation_state.step_size)) + + return ( + (new_state, new_adaptation_state), + adaptation_info_fn(new_state, info, new_adaptation_state), + ) + + def run(rng_key: PRNGKey, position: ArrayLikeTree, num_steps: int = 1000): + init_key, rng_key, alba_key = jax.random.split(rng_key, 3) + init_state = algorithm.init(position=position, logdensity_fn=logdensity_fn, random_generator_arg=init_key) + init_adaptation_state = adapt_init(position) + + if progress_bar: + print("Running window adaptation") + scan_fn = gen_scan_fn(num_steps-num_alba_steps, progress_bar=progress_bar) + start_state = (init_state, init_adaptation_state) + keys = jax.random.split(rng_key, num_steps-num_alba_steps) + schedule = build_schedule(num_steps-num_alba_steps) + last_state, info = scan_fn( + one_step, + start_state, + (jnp.arange(num_steps-num_alba_steps), keys, schedule), + ) + + last_chain_state, last_warmup_state, *_ = last_state + step_size, L, inverse_mass_matrix = adapt_final(last_warmup_state) + + # jax.debug.print("unadjusted L before alba: {params}", params=(L, step_size)) + + ### + ### ALBA TUNING + ### + + jax.debug.print("num_alba_steps: {x}", x=num_alba_steps) + + max_num_steps = 200 + thinning_rate = math.ceil(num_alba_steps / max_num_steps) + jax.debug.print("thinning_rate: {x}", x=thinning_rate) + new_num_alba_steps = math.ceil(num_alba_steps / thinning_rate) + jax.debug.print("new_num_alba_steps: {x}", x=new_num_alba_steps) + + keys = jax.random.split(alba_key, new_num_alba_steps) + mcmc_kernel = algorithm.build_kernel(integrator) + + def step(state, key): + next_state=state + for i in range(thinning_rate): + key = jax.random.fold_in(key, i) + next_state, _ = mcmc_kernel( + rng_key=key, + state=state, + logdensity_fn=logdensity_fn, + L=L, + step_size=step_size, + inverse_mass_matrix=inverse_mass_matrix, + ) + + return next_state, next_state.position + + if new_num_alba_steps > 0: + jax.debug.print("params before alba tuning {x}", x=(L, step_size)) + _, samples = jax.lax.scan(step, last_chain_state, keys) + flat_samples = jax.vmap(lambda x: ravel_pytree(x)[0])(samples) + ess = effective_sample_size(flat_samples[None, ...]) + jax.debug.print("ess after alba {x}", x=(L, step_size, ess)) + # print(num_alba_steps/jnp.mean(ess), "ess (blackjax internal)\n") + # print( effective_sample_size(flat_samples[None, ...]), "ess (blackjax internal)\n") + + # print("L etc", L, step_size, jnp.mean(ess), num_alba_steps, jnp.mean(num_alba_steps / ess)) + L=alba_factor * step_size * jnp.mean(new_num_alba_steps / ess) + # print("new L", L) + # raise Exception("stop") + + # else: + # ess = 0.0 + + max_num_steps = 500 + + # jax.debug.print("L: {x}", x=step_size*50.) + parameters = { + "step_size": step_size, + "inverse_mass_matrix": inverse_mass_matrix, + "L": jnp.clip(L, max=step_size*max_num_steps), + "ESS": jnp.mean(ess)/num_alba_steps, + **extra_parameters, + } + + # jax.debug.print("parameters {x}", x=parameters) + + return ( + AdaptationResults( + last_chain_state, + parameters, + ), + info, + ) + + return AdaptationAlgorithm(run) + + + diff --git a/blackjax/adaptation/unadjusted_step_size.py b/blackjax/adaptation/unadjusted_step_size.py new file mode 100644 index 000000000..c0753345b --- /dev/null +++ b/blackjax/adaptation/unadjusted_step_size.py @@ -0,0 +1,74 @@ +import jax.numpy as jnp +from typing import NamedTuple +import jax + +class RobnikStepSizeTuningState(NamedTuple): + time : jnp.ndarray + step_size: float + x_average: float + step_size_max: float + num_dimensions: int + +def robnik_step_size_tuning(desired_energy_var, trust_in_estimate=1.5, num_effective_samples=150, step_size_max=jnp.inf, step_size_reduction_factor=0.8): + + decay_rate = (num_effective_samples - 1.0) / (num_effective_samples + 1.0) + + def init(initial_step_size, num_dimensions): + return RobnikStepSizeTuningState(time=0.0, x_average=0.0, step_size=initial_step_size, step_size_max=step_size_max, num_dimensions=num_dimensions) + + def update(robnik_state, info): + + # jax.debug.print("robnik state: {x}", x=robnik_state) + # jax.debug.print("info: {x}", x=(info.energy_change, info.nonans)) + # raise Exception("Stop here") + + + + energy_change = info.energy_change + + + xi = ( + jnp.square(energy_change) / (robnik_state.num_dimensions * desired_energy_var) + ) + 1e-8 # 1e-8 is added to avoid divergences in log xi + weight = jnp.exp( + -0.5 * jnp.square(jnp.log(xi) / (6.0 * trust_in_estimate)) + ) # the weight reduces the impact of stepsizes which are much larger on much smaller than the desired one. + + x_average = decay_rate * robnik_state.x_average + weight * ( + xi / jnp.power(robnik_state.step_size, 6.0) + ) + + time = decay_rate * robnik_state.time + weight + step_size = jnp.power( + x_average / time, -1.0 / 6.0 + ) # We use the Var[E] = O(eps^6) relation here. + step_size = (step_size < robnik_state.step_size_max) * step_size + ( + step_size > robnik_state.step_size_max + ) * robnik_state.step_size_max # if the proposed stepsize is above the stepsize where we have seen divergences + # jax.debug.print("new step_size: {x}", x=(step_size)) + + # old_robnik_state = robnik_state + + # old_robnik_step_size = robnik_state.step_size + # jax.debug.print("step_size: {x}", x=(old_robnik_step_size, old_robnik_step_size * step_size_reduction_factor, step_size)) + # jax.debug.print("stuff {x}", x=(x_average, time, robnik_state.time, time)) + old_robnik_state = robnik_state + + + + robnik_state = jax.lax.cond( + info.nonans, + lambda: RobnikStepSizeTuningState(time=time, x_average=x_average, step_size=step_size, step_size_max=step_size_max, num_dimensions=robnik_state.num_dimensions), + lambda: robnik_state._replace(step_size=robnik_state.step_size * step_size_reduction_factor), + ) + # jax.debug.print("robnik_state: {robnik_state}", robnik_state=(robnik_state.step_size, info.nonans, robnik_state.step_size * step_size_reduction_factor)) + # jax.debug.print("robnik_state: {x}", x=(old_robnik_state.step_size, robnik_state.step_size)) + return robnik_state + + # return RobnikStepSizeTuningState(time=time, x_average=x_average, step_size=step_size, step_size_max=step_size_max, num_dimensions=robnik_state.num_dimensions) + + + def final(robnik_state): + return robnik_state.step_size + + return init, update, final diff --git a/blackjax/adaptation/window_adaptation.py b/blackjax/adaptation/window_adaptation.py index 69a098325..18dd76cbb 100644 --- a/blackjax/adaptation/window_adaptation.py +++ b/blackjax/adaptation/window_adaptation.py @@ -45,6 +45,7 @@ class WindowAdaptationState(NamedTuple): def base( is_mass_matrix_diagonal: bool, target_acceptance_rate: float = 0.80, + preconditioning = True, ) -> tuple[Callable, Callable, Callable]: """Warmup scheme for sampling procedures based on euclidean manifold HMC. The schedule and algorithms used match Stan's :cite:p:`stan_hmc_param` as closely as possible. @@ -100,6 +101,9 @@ def base( """ mm_init, mm_update, mm_final = mass_matrix_adaptation(is_mass_matrix_diagonal) + if not preconditioning: + mm_update = lambda x, y: x + mm_final = lambda x: x da_init, da_update, da_final = dual_averaging_adaptation(target_acceptance_rate) def init( @@ -164,6 +168,7 @@ def slow_update( """ new_imm_state = mm_update(warmup_state.imm_state, position) + # new_imm_state = warmup_state.imm_state new_ss_state = da_update(warmup_state.ss_state, acceptance_rate) new_step_size = jnp.exp(new_ss_state.log_step_size) @@ -251,6 +256,7 @@ def window_adaptation( progress_bar: bool = False, adaptation_info_fn: Callable = return_all_adapt_info, integrator=mcmc.integrators.velocity_verlet, + preconditioning = True, **extra_parameters, ) -> AdaptationAlgorithm: """Adapt the value of the inverse mass matrix and step size parameters of @@ -301,6 +307,7 @@ def window_adaptation( adapt_init, adapt_step, adapt_final = base( is_mass_matrix_diagonal, target_acceptance_rate=target_acceptance_rate, + preconditioning=preconditioning, ) def one_step(carry, xs): diff --git a/blackjax/diagnostics.py b/blackjax/diagnostics.py index 257ce759c..fd184d048 100644 --- a/blackjax/diagnostics.py +++ b/blackjax/diagnostics.py @@ -207,3 +207,19 @@ def monotone_sequence_body_fn(rho_hat_sum_tm1, rho_hat_sum_t): ess = ess_raw / tau_hat return ess.squeeze() + + +def splitR(position, num_chains, superchain_size, func_for_splitR = jnp.square): + + # combine the chains in super-chains to compute expectation values + func_mk = jax.vmap(func_for_splitR)(position) # shape = (# chains, # func) + func_mk = func_mk.reshape(num_chains // superchain_size, superchain_size, func_mk.shape[-1]) #shape = (# superchains, # chains in superchain, # func) + func_k = jnp.average(func_mk, axis = 1) #shape = (# superchains, # func) + func_sq_k = jnp.average(jnp.square(func_mk), axis = 1) #shape = (# superchains, # func) + W_k = (func_sq_k - jnp.square(func_k)) * superchain_size / (superchain_size - 1) # variance withing k-th superchain + W = jnp.average(W_k, axis = 0) # average within superchain variance + B = jnp.var(func_k, axis = 0, ddof= 1) # between superchain variance + + R = jnp.sqrt(1. + (B/W)) # splitR, shape = (# func) + + return R \ No newline at end of file diff --git a/blackjax/mcmc/__init__.py b/blackjax/mcmc/__init__.py index 8acb28274..47bc0837f 100644 --- a/blackjax/mcmc/__init__.py +++ b/blackjax/mcmc/__init__.py @@ -1,17 +1,22 @@ from . import ( adjusted_mclmc, adjusted_mclmc_dynamic, + malt, + dynamic_malt, barker, elliptical_slice, ghmc, hmc, + uhmc, mala, marginal_latent_gaussian, mclmc, + mchmc, nuts, periodic_orbital, random_walk, rmhmc, + underdamped_langevin ) __all__ = [ @@ -26,6 +31,11 @@ "marginal_latent_gaussian", "random_walk", "mclmc", + "mchmc", + "underdamped_langevin", + "uhmc", "adjusted_mclmc_dynamic", "adjusted_mclmc", + "dynamic_malt", + "malt", ] diff --git a/blackjax/mcmc/adjusted_mclmc.py b/blackjax/mcmc/adjusted_mclmc.py index f390402f2..747bedc4c 100644 --- a/blackjax/mcmc/adjusted_mclmc.py +++ b/blackjax/mcmc/adjusted_mclmc.py @@ -11,11 +11,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -"""Public API for the Metropolis Hastings Microcanonical Hamiltonian Monte Carlo (MHMCHMC) Kernel. This is closely related to the Microcanonical Langevin Monte Carlo (MCLMC) Kernel, which is an unadjusted method. This kernel adds a Metropolis-Hastings correction to the MCLMC kernel. It also only refreshes the momentum variable after each MH step, rather than during the integration of the trajectory. Hence "Hamiltonian" and not "Langevin". - -NOTE: For best performance, we recommend using adjusted_mclmc_dynamic instead of this module, which is primarily intended for use in parallelized versions of the algorithm. - -""" +"""Public API for the Metropolis Hastings Microcanonical Hamiltonian Monte Carlo (MHMCHMC) Kernel. This is closely related to the Microcanonical Langevin Monte Carlo (MCLMC) Kernel, which is an unadjusted method. This kernel adds a Metropolis-Hastings correction to the MCLMC kernel. It also only refreshes the momentum variable after each MH step, rather than during the integration of the trajectory. Hence "Hamiltonian" and not "Langevin".""" from typing import Callable, Union import jax @@ -23,9 +19,10 @@ import blackjax.mcmc.integrators as integrators from blackjax.base import SamplingAlgorithm -from blackjax.mcmc.hmc import HMCInfo, HMCState +from blackjax.mcmc.hmc import HMCState +from blackjax.mcmc.hmc import HMCInfo from blackjax.mcmc.proposal import static_binomial_sampling -from blackjax.types import ArrayLikeTree, ArrayTree, PRNGKey +from blackjax.types import Array, ArrayLikeTree, ArrayTree, PRNGKey from blackjax.util import generate_unit_vector __all__ = ["init", "build_kernel", "as_top_level_api"] @@ -37,12 +34,12 @@ def init(position: ArrayLikeTree, logdensity_fn: Callable): def build_kernel( - logdensity_fn: Callable, integrator: Callable = integrators.isokinetic_mclachlan, divergence_threshold: float = 1000, - inverse_mass_matrix=1.0, + next_random_arg_fn: Callable = lambda key: jax.random.split(key)[1], + L_proposal_factor: float = jnp.inf, ): - """Build an MHMCHMC kernel where the number of integration steps is chosen randomly. + """Build a Dynamic MHMCHMC kernel where the number of integration steps is chosen randomly. Parameters ---------- @@ -66,12 +63,17 @@ def build_kernel( def kernel( rng_key: PRNGKey, state: HMCState, + logdensity_fn: Callable, step_size: float, - num_integration_steps: int, - L_proposal_factor: float = jnp.inf, + integration_steps_fn, + inverse_mass_matrix=1.0, ) -> tuple[HMCState, HMCInfo]: """Generate a new sample with the MHMCHMC kernel.""" + + # num_integration_steps = integration_steps_fn(state.random_generator_arg) + num_integration_steps = integration_steps_fn(None) + key_momentum, key_integrator = jax.random.split(rng_key, 2) momentum = generate_unit_vector(key_momentum, state.position) proposal, info, _ = adjusted_mclmc_proposal( @@ -96,6 +98,7 @@ def kernel( proposal.position, proposal.logdensity, proposal.logdensity_grad, + # next_random_arg_fn(state.random_generator_arg), ), info, ) @@ -111,9 +114,10 @@ def as_top_level_api( *, divergence_threshold: int = 1000, integrator: Callable = integrators.isokinetic_mclachlan, - num_integration_steps, + next_random_arg_fn: Callable = lambda key: jax.random.split(key)[1], + integration_steps_fn: Callable = lambda key: jax.random.randint(key, (), 1, 10), ) -> SamplingAlgorithm: - """Implements the (basic) user interface for the MHMCHMC kernel. + """Implements the (basic) user interface for the dynamic MHMCHMC kernel. Parameters ---------- @@ -140,23 +144,23 @@ def as_top_level_api( """ kernel = build_kernel( - logdensity_fn=logdensity_fn, integrator=integrator, - inverse_mass_matrix=inverse_mass_matrix, + next_random_arg_fn=next_random_arg_fn, divergence_threshold=divergence_threshold, + L_proposal_factor=L_proposal_factor, ) - def init_fn(position: ArrayLikeTree, rng_key=None): - del rng_key - return init(position, logdensity_fn) + def init_fn(position: ArrayLikeTree, rng_key: Array): + return init(position, logdensity_fn, rng_key) def update_fn(rng_key: PRNGKey, state): return kernel( rng_key=rng_key, state=state, + logdensity_fn=logdensity_fn, step_size=step_size, - num_integration_steps=num_integration_steps, - L_proposal_factor=L_proposal_factor, + integration_steps_fn=integration_steps_fn, + inverse_mass_matrix=inverse_mass_matrix, ) return SamplingAlgorithm(init_fn, update_fn) # type: ignore[arg-type] @@ -240,3 +244,29 @@ def generate( return sampled_state, info, other_proposal_info return generate + + +def rescale(mu): + """returns s, such that + round(U(0, 1) * s + 0.5) + has expected value mu. + """ + k = jnp.floor(2 * mu - 1) + x = k * (mu - 0.5 * (k + 1)) / (k + 1 - mu) + return k + x + + +def trajectory_length(t, mu): + s = rescale(mu) + return jnp.rint(0.5 + halton_sequence(t) * s) + +def make_random_trajectory_length_fn(random_trajectory_length : bool): + if random_trajectory_length: + integration_steps_fn = lambda avg_num_integration_steps: lambda k: (jnp.clip(jnp.ceil( + jax.random.uniform(k) * rescale(avg_num_integration_steps) + ), min=1)).astype('int32') + else: + integration_steps_fn = lambda avg_num_integration_steps: lambda _: jnp.clip(jnp.ceil( + avg_num_integration_steps + ), min=1).astype('int32') + return integration_steps_fn \ No newline at end of file diff --git a/blackjax/mcmc/adjusted_mclmc_dynamic.py b/blackjax/mcmc/adjusted_mclmc_dynamic.py index 1a69e1a28..b51a4d551 100644 --- a/blackjax/mcmc/adjusted_mclmc_dynamic.py +++ b/blackjax/mcmc/adjusted_mclmc_dynamic.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. """Public API for the Metropolis Hastings Microcanonical Hamiltonian Monte Carlo (MHMCHMC) Kernel. This is closely related to the Microcanonical Langevin Monte Carlo (MCLMC) Kernel, which is an unadjusted method. This kernel adds a Metropolis-Hastings correction to the MCLMC kernel. It also only refreshes the momentum variable after each MH step, rather than during the integration of the trajectory. Hence "Hamiltonian" and not "Langevin".""" -from typing import Callable, Union +from typing import Callable, NamedTuple, Union import jax import jax.numpy as jnp @@ -20,13 +20,22 @@ import blackjax.mcmc.integrators as integrators from blackjax.base import SamplingAlgorithm from blackjax.mcmc.dynamic_hmc import DynamicHMCState, halton_sequence -from blackjax.mcmc.hmc import HMCInfo +# from blackjax.mcmc.hmc import HMCInfo from blackjax.mcmc.proposal import static_binomial_sampling from blackjax.types import Array, ArrayLikeTree, ArrayTree, PRNGKey from blackjax.util import generate_unit_vector __all__ = ["init", "build_kernel", "as_top_level_api"] +class MAMSInfo(NamedTuple): + + # momentum: ArrayTree + acceptance_rate: float + is_accepted: bool + is_divergent: bool + energy: float + # proposal: integrators.IntegratorState + num_integration_steps: int def init(position: ArrayLikeTree, logdensity_fn: Callable, random_generator_arg: Array): logdensity, logdensity_grad = jax.value_and_grad(logdensity_fn)(position) @@ -34,11 +43,10 @@ def init(position: ArrayLikeTree, logdensity_fn: Callable, random_generator_arg: def build_kernel( - integration_steps_fn, integrator: Callable = integrators.isokinetic_mclachlan, divergence_threshold: float = 1000, next_random_arg_fn: Callable = lambda key: jax.random.split(key)[1], - inverse_mass_matrix=1.0, + L_proposal_factor: float = jnp.inf, ): """Build a Dynamic MHMCHMC kernel where the number of integration steps is chosen randomly. @@ -66,12 +74,24 @@ def kernel( state: DynamicHMCState, logdensity_fn: Callable, step_size: float, - L_proposal_factor: float = jnp.inf, - ) -> tuple[DynamicHMCState, HMCInfo]: + integration_steps_fn, + inverse_mass_matrix=1.0, + ) -> tuple[DynamicHMCState, MAMSInfo]: """Generate a new sample with the MHMCHMC kernel.""" + # return state, HMCInfo( + # state.position, + # 0.0, + # False, + # False, + # state.logdensity, + # None, + # 0, + # ) + num_integration_steps = integration_steps_fn(state.random_generator_arg) + key_momentum, key_integrator = jax.random.split(rng_key, 2) momentum = generate_unit_vector(key_momentum, state.position) proposal, info, _ = adjusted_mclmc_proposal( @@ -142,11 +162,10 @@ def as_top_level_api( """ kernel = build_kernel( - integration_steps_fn=integration_steps_fn, integrator=integrator, next_random_arg_fn=next_random_arg_fn, - inverse_mass_matrix=inverse_mass_matrix, divergence_threshold=divergence_threshold, + L_proposal_factor=L_proposal_factor, ) def init_fn(position: ArrayLikeTree, rng_key: Array): @@ -154,11 +173,12 @@ def init_fn(position: ArrayLikeTree, rng_key: Array): def update_fn(rng_key: PRNGKey, state): return kernel( - rng_key, - state, - logdensity_fn, - step_size, - L_proposal_factor, + rng_key=rng_key, + state=state, + logdensity_fn=logdensity_fn, + step_size=step_size, + integration_steps_fn=integration_steps_fn, + inverse_mass_matrix=inverse_mass_matrix, ) return SamplingAlgorithm(init_fn, update_fn) # type: ignore[arg-type] @@ -216,7 +236,7 @@ def build_trajectory(state, num_integration_steps, rng_key): def generate( rng_key, state: integrators.IntegratorState - ) -> tuple[integrators.IntegratorState, HMCInfo, ArrayTree]: + ) -> tuple[integrators.IntegratorState, MAMSInfo, ArrayTree]: """Generate a new chain state.""" end_state, kinetic_energy, rng_key = build_trajectory( state, num_integration_steps, rng_key @@ -229,13 +249,13 @@ def generate( sampled_state, info = sample_proposal(rng_key, delta_energy, state, end_state) do_accept, p_accept, other_proposal_info = info - info = HMCInfo( - state.momentum, + info = MAMSInfo( + # state.momentum, p_accept, do_accept, is_diverging, new_energy, - end_state, + # end_state, num_integration_steps, ) @@ -257,3 +277,14 @@ def rescale(mu): def trajectory_length(t, mu): s = rescale(mu) return jnp.rint(0.5 + halton_sequence(t) * s) + +def make_random_trajectory_length_fn(random_trajectory_length : bool): + if random_trajectory_length: + integration_steps_fn = lambda avg_num_integration_steps: lambda k: (jnp.clip(jnp.ceil( + jax.random.uniform(k) * rescale(avg_num_integration_steps) + ), min=1)).astype('int32') + else: + integration_steps_fn = lambda avg_num_integration_steps: lambda _: jnp.clip(jnp.ceil( + avg_num_integration_steps + ), min=1).astype('int32') + return integration_steps_fn \ No newline at end of file diff --git a/blackjax/mcmc/dynamic_hmc.py b/blackjax/mcmc/dynamic_hmc.py index de77be825..2916d0262 100644 --- a/blackjax/mcmc/dynamic_hmc.py +++ b/blackjax/mcmc/dynamic_hmc.py @@ -1,3 +1,4 @@ + # Copyright 2020- The Blackjax Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -55,7 +56,6 @@ def build_kernel( integrator: Callable = integrators.velocity_verlet, divergence_threshold: float = 1000, next_random_arg_fn: Callable = lambda key: jax.random.split(key)[1], - integration_steps_fn: Callable = lambda key: jax.random.randint(key, (), 1, 10), ): """Build a Dynamic HMC kernel where the number of integration steps is chosen randomly. @@ -86,6 +86,7 @@ def kernel( logdensity_fn: Callable, step_size: float, inverse_mass_matrix: Array, + integration_steps_fn: Callable, **integration_steps_kwargs, ) -> tuple[DynamicHMCState, HMCInfo]: """Generate a new sample with the HMC kernel.""" @@ -154,7 +155,7 @@ def as_top_level_api( A ``SamplingAlgorithm``. """ kernel = build_kernel( - integrator, divergence_threshold, next_random_arg_fn, integration_steps_fn + integrator, divergence_threshold, next_random_arg_fn, ) def init_fn(position: ArrayLikeTree, rng_key: Array): @@ -170,6 +171,7 @@ def step_fn(rng_key: PRNGKey, state): logdensity_fn, step_size, inverse_mass_matrix, + integration_steps_fn ) return SamplingAlgorithm(init_fn, step_fn) diff --git a/blackjax/mcmc/dynamic_malt.py b/blackjax/mcmc/dynamic_malt.py new file mode 100644 index 000000000..91c1e592f --- /dev/null +++ b/blackjax/mcmc/dynamic_malt.py @@ -0,0 +1,194 @@ +# Copyright 2020- The Blackjax Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Public API for the Dynamic HMC Kernel""" +from typing import Callable, NamedTuple + +import jax +import jax.numpy as jnp + +import blackjax.mcmc.integrators as integrators +from blackjax.base import SamplingAlgorithm +from blackjax.mcmc.hmc import HMCInfo, HMCState +from blackjax.mcmc.malt import build_kernel as build_static_hmc_kernel +from blackjax.types import Array, ArrayLikeTree, ArrayTree, PRNGKey +from blackjax.mcmc.dynamic_hmc import DynamicHMCState + +__all__ = [ + "DynamicHMCState", + "init", + "build_kernel", + "halton_sequence", + "as_top_level_api", +] + + + + +def init(position: ArrayLikeTree, logdensity_fn: Callable, random_generator_arg: Array): + logdensity, logdensity_grad = jax.value_and_grad(logdensity_fn)(position) + return DynamicHMCState(position, logdensity, logdensity_grad, random_generator_arg) + + +def build_kernel( + integrator: Callable = integrators.velocity_verlet, + divergence_threshold: float = 1000, + next_random_arg_fn: Callable = lambda key: jax.random.split(key)[1], + L_proposal_factor: float = jnp.inf, +): + """Build a Dynamic HMC kernel where the number of integration steps is chosen randomly. + + Parameters + ---------- + integrator + The symplectic integrator to use to integrate the Hamiltonian dynamics. + divergence_threshold + Value of the difference in energy above which we consider that the transition is divergent. + next_random_arg_fn + Function that generates the next `random_generator_arg` from its previous value. + integration_steps_fn + Function that generates the next pseudo or quasi-random number of integration steps in the + sequence, given the current `random_generator_arg`. Needs to return an `int`. + + Returns + ------- + A kernel that takes a rng_key and a Pytree that contains the current state + of the chain and that returns a new state of the chain along with + information about the transition. + + """ + + hmc_base = build_static_hmc_kernel(integrator, divergence_threshold, L_proposal_factor) + + def kernel( + rng_key: PRNGKey, + state: DynamicHMCState, + logdensity_fn: Callable, + step_size: float, + inverse_mass_matrix: Array, + integration_steps_fn: Callable = lambda key: jax.random.randint(key, (), 1, 10), + **integration_steps_kwargs, + ) -> tuple[DynamicHMCState, HMCInfo]: + """Generate a new sample with the HMC kernel.""" + + + num_integration_steps = integration_steps_fn( + state.random_generator_arg, **integration_steps_kwargs + ).astype(int) + + # jax.debug.print("num_integration_steps {x}", x=(num_integration_steps, step_size, inverse_mass_matrix)) + + hmc_state = HMCState(state.position, state.logdensity, state.logdensity_grad) + hmc_proposal, info = hmc_base( + rng_key, + hmc_state, + logdensity_fn, + step_size, + inverse_mass_matrix, + num_integration_steps, + ) + + next_random_arg = next_random_arg_fn(state.random_generator_arg) + return ( + DynamicHMCState( + hmc_proposal.position, + hmc_proposal.logdensity, + hmc_proposal.logdensity_grad, + next_random_arg, + ), + info, + ) + + return kernel + + +def as_top_level_api( + logdensity_fn: Callable, + step_size: float, + inverse_mass_matrix: Array, + *, + divergence_threshold: int = 1000, + integrator: Callable = integrators.velocity_verlet, + next_random_arg_fn: Callable = lambda key: jax.random.split(key)[1], + integration_steps_fn: Callable = lambda key: jax.random.randint(key, (), 1, 10), + L_proposal_factor: float = jnp.inf, +) -> SamplingAlgorithm: + """Implements the (basic) user interface for the dynamic HMC kernel. + + Parameters + ---------- + logdensity_fn + The log-density function we wish to draw samples from. + step_size + The value to use for the step size in the symplectic integrator. + inverse_mass_matrix + The value to use for the inverse mass matrix when drawing a value for + the momentum and computing the kinetic energy. + divergence_threshold + The absolute value of the difference in energy between two states above + which we say that the transition is divergent. The default value is + commonly found in other libraries, and yet is arbitrary. + integrator + (algorithm parameter) The symplectic integrator to use to integrate the trajectory. + next_random_arg_fn + Function that generates the next `random_generator_arg` from its previous value. + integration_steps_fn + Function that generates the next pseudo or quasi-random number of integration steps in the + sequence, given the current `random_generator_arg`. + + + Returns + ------- + A ``SamplingAlgorithm``. + """ + kernel = build_kernel( + integrator, divergence_threshold, next_random_arg_fn, L_proposal_factor + ) + + def init_fn(position: ArrayLikeTree, rng_key: Array): + # Note that rng_key here is not necessarily a PRNGKey, could be a Array that + # for generates a sequence of pseudo or quasi-random numbers (previously + # named as `random_generator_arg`) + return init(position, logdensity_fn, rng_key) + + def step_fn(rng_key: PRNGKey, state): + return kernel( + rng_key, + state, + logdensity_fn, + step_size, + inverse_mass_matrix, + integration_steps_fn, + ) + + return SamplingAlgorithm(init_fn, step_fn) + + +def halton_sequence(i: Array, max_bits: int = 10) -> float: + bit_masks = 2 ** jnp.arange(max_bits, dtype=i.dtype) + return jnp.einsum("i,i->", jnp.mod((i + 1) // bit_masks, 2), 0.5 / bit_masks) + + +def rescale(mu): + # Returns s, such that `round(U(0, 1) * s + 0.5)` has expected value mu. + k = jnp.floor(2 * mu - 1) + x = k * (mu - 0.5 * (k + 1)) / (k + 1 - mu) + return k + x + + +def halton_trajectory_length( + i: Array, trajectory_length_adjustment: float, max_bits: int = 10 +) -> int: + """Generate a quasi-random number of integration steps.""" + s = rescale(trajectory_length_adjustment) + return jnp.asarray(jnp.rint(0.5 + halton_sequence(i, max_bits) * s), dtype=int) diff --git a/blackjax/mcmc/hmc.py b/blackjax/mcmc/hmc.py index 452b94e44..384c96b28 100644 --- a/blackjax/mcmc/hmc.py +++ b/blackjax/mcmc/hmc.py @@ -121,6 +121,7 @@ def kernel( num_integration_steps: int, ) -> tuple[HMCState, HMCInfo]: """Generate a new sample with the HMC kernel.""" + metric = metrics.default_metric(inverse_mass_matrix) symplectic_integrator = integrator(logdensity_fn, metric.kinetic_energy) @@ -134,7 +135,10 @@ def kernel( key_momentum, key_integrator = jax.random.split(rng_key, 2) - position, logdensity, logdensity_grad = state + # position, logdensity, logdensity_grad = state + position = state.position + logdensity = state.logdensity + logdensity_grad = state.logdensity_grad momentum = metric.sample_momentum(key_momentum, position) integrator_state = integrators.IntegratorState( @@ -302,6 +306,7 @@ def generate( is_diverging = -delta_energy > divergence_threshold sampled_state, info = sample_proposal(rng_key, delta_energy, state, end_state) do_accept, p_accept, other_proposal_info = info + info = HMCInfo( state.momentum, @@ -335,4 +340,4 @@ def flip_momentum( flipped_momentum, state.logdensity, state.logdensity_grad, - ) + ) \ No newline at end of file diff --git a/blackjax/mcmc/integrators.py b/blackjax/mcmc/integrators.py index 0effa204e..13987b98f 100644 --- a/blackjax/mcmc/integrators.py +++ b/blackjax/mcmc/integrators.py @@ -21,6 +21,7 @@ from blackjax.mcmc.metrics import KineticEnergy from blackjax.types import ArrayTree +from blackjax.mcmc.metrics import default_metric __all__ = [ "mclachlan", @@ -28,6 +29,7 @@ "velocity_verlet", "yoshida", "with_isokinetic_maruyama", + "with_maruyama", "isokinetic_velocity_verlet", "isokinetic_mclachlan", "isokinetic_omelyan", @@ -98,7 +100,12 @@ def generalized_two_stage_integrator( """ def one_step(state: IntegratorState, step_size: float): - position, momentum, _, logdensity_grad = state + # position, momentum, _, logdensity_grad = state + position = state.position + momentum = state.momentum + logdensity_grad = state.logdensity_grad + # logdensity = state.logdensity + # jax.debug.print("initial state {x}", x=jnp.any(jnp.isnan(momentum))) # auxiliary infomation generated during integration for diagnostics. It is # updated by the operator1 and operator2 at each call. momentum_update_info = None @@ -113,6 +120,7 @@ def one_step(state: IntegratorState, step_size: float): momentum_update_info, is_last_call=False, ) + # jax.debug.print("momentum inside {x}", x=momentum) else: ( position, @@ -163,12 +171,17 @@ def update( coef: float, auxiliary_info=None, ): + + + # jax.debug.print("nan? {x}", x=jnp.any(jnp.isnan(kinetic_grad))) + # jax.debug.print("position {x}", x=position) del auxiliary_info new_position = jax.tree_util.tree_map( lambda x, grad: x + step_size * coef * grad, position, kinetic_grad, ) + # jax.debug.print("new position {x}", x=new_position) logdensity, logdensity_grad = logdensity_and_grad_fn(new_position) return new_position, logdensity, logdensity_grad, None @@ -187,11 +200,14 @@ def update( is_last_call=False, ): del auxiliary_info + # jax.debug.print("momentum {x}", x=momentum) + # jax.debug.print("force {x}", x=logdensity_grad[0]) new_momentum = jax.tree_util.tree_map( lambda x, grad: x + step_size * coef * grad, momentum, logdensity_grad, ) + # jax.debug.print("new momentum {x}", x=new_momentum) if is_last_call: return new_momentum, None, None kinetic_grad = kinetic_energy_grad_fn(new_momentum) @@ -305,14 +321,14 @@ def euclidean_integrator( omelyan = generate_euclidean_integrator(omelyan_coefficients) -# Intergrators with non Euclidean updates +# Integrators with non Euclidean updates def _normalized_flatten_array(x, tol=1e-13): norm = jnp.linalg.norm(x) return jnp.where(norm > tol, x / norm, x), norm def esh_dynamics_momentum_update_one_step(inverse_mass_matrix=1.0): - sqrt_inverse_mass_matrix = jnp.sqrt(inverse_mass_matrix) + sqrt_inverse_mass_matrix = jax.tree_util.tree_map(jnp.sqrt, inverse_mass_matrix) def update( momentum: ArrayTree, @@ -330,7 +346,7 @@ def update( """ del is_last_call - logdensity_grad = logdensity_grad + # logdensity_grad = logdensity_grad flatten_grads, unravel_fn = ravel_pytree(logdensity_grad) flatten_grads = flatten_grads * sqrt_inverse_mass_matrix flatten_momentum, _ = ravel_pytree(momentum) @@ -353,6 +369,7 @@ def update( ) * (dims - 1) if previous_kinetic_energy_change is not None: kinetic_energy_change += previous_kinetic_energy_change + return next_momentum, gr, kinetic_energy_change return update @@ -398,7 +415,7 @@ def isokinetic_integrator( isokinetic_omelyan = generate_isokinetic_integrator(omelyan_coefficients) -def partially_refresh_momentum(momentum, rng_key, step_size, L): +def partially_refresh_momentum_isokinetic(momentum, rng_key, step_size, L): """Adds a small noise to momentum and normalizes. Parameters @@ -422,7 +439,46 @@ def partially_refresh_momentum(momentum, rng_key, step_size, L): nu = jnp.sqrt((jnp.exp(2 * step_size / L) - 1.0) / dim) z = nu * normal(rng_key, shape=m.shape, dtype=m.dtype) new_momentum = unravel_fn((m + z) / jnp.linalg.norm(m + z)) - # return new_momentum + + return jax.lax.cond( + jnp.isinf(L), + lambda _: momentum, + lambda _: new_momentum, + operand=None, + ) + + +def partially_refresh_momentum(momentum, rng_key, step_size, L, inverse_mass_matrix): + """Adds a small noise to momentum and normalizes. + + Parameters + ---------- + rng_key + The pseudo-random number generator key used to generate random numbers. + momentum + PyTree that the structure the output should to match. + step_size + Step size + L + controls rate of momentum change + + Returns + ------- + momentum with random change in angle + """ + + # TODO + m, unravel_fn = ravel_pytree(momentum) + # m = jax.tree_util.tree_map(lambda x: x * jnp.sqrt(inverse_mass_matrix), m) + # dim = m.shape[0] + c1 = jnp.exp(-step_size/L) + c2 = jnp.sqrt((1-c1**2)) + # z = normal(rng_key, shape=m.shape, dtype=m.dtype) + metric = default_metric(inverse_mass_matrix) + z = metric.sample_momentum(rng_key, m) + # normal(rng_key, shape=m.shape, dtype=m.dtype) + new_momentum = unravel_fn(c1*m + c2*z) + return jax.lax.cond( jnp.isinf(L), lambda _: momentum, @@ -436,7 +492,7 @@ def stochastic_integrator(init_state, step_size, L_proposal, rng_key): key1, key2 = jax.random.split(rng_key) # partial refreshment state = init_state._replace( - momentum=partially_refresh_momentum( + momentum=partially_refresh_momentum_isokinetic( momentum=init_state.momentum, rng_key=key1, L=L_proposal, @@ -448,7 +504,7 @@ def stochastic_integrator(init_state, step_size, L_proposal, rng_key): # partial refreshment state = state._replace( - momentum=partially_refresh_momentum( + momentum=partially_refresh_momentum_isokinetic( momentum=state.momentum, rng_key=key2, L=L_proposal, @@ -460,6 +516,49 @@ def stochastic_integrator(init_state, step_size, L_proposal, rng_key): return stochastic_integrator +def with_maruyama(integrator, kinetic_energy,inverse_mass_matrix): + def stochastic_integrator(init_state, step_size, L_proposal, rng_key): + key1, key2 = jax.random.split(rng_key) + # partial refreshment + # jax.debug.print("state 1 {x}",x=init_state) + state = init_state._replace( + momentum=partially_refresh_momentum( + momentum=init_state.momentum, + rng_key=key1, + L=L_proposal, + step_size=step_size * 0.5, + inverse_mass_matrix=inverse_mass_matrix, + ) + ) + # jax.debug.print("state 1.5 {x}",x=state) + # one step of the deterministic dynamics + new_state = integrator(state, step_size) + # jax.debug.print("state 2 {x}",x=state) + + kinetic_change = - kinetic_energy(state.momentum) + kinetic_energy( + new_state.momentum + ) + energy_change = kinetic_change - new_state.logdensity + state.logdensity + + # partial refreshment + state = new_state._replace( + momentum=partially_refresh_momentum( + momentum=new_state.momentum, + rng_key=key2, + L=L_proposal, + step_size=step_size * 0.5, + inverse_mass_matrix=inverse_mass_matrix, + ) + ) + + + + + return state, (kinetic_change, energy_change) + + return stochastic_integrator + + FixedPointSolver = Callable[ [Callable[[ArrayTree], Tuple[ArrayTree, ArrayTree]], ArrayTree], Tuple[ArrayTree, ArrayTree, Any], diff --git a/blackjax/mcmc/malt.py b/blackjax/mcmc/malt.py new file mode 100644 index 000000000..395655bce --- /dev/null +++ b/blackjax/mcmc/malt.py @@ -0,0 +1,315 @@ +# Copyright 2020- The Blackjax Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Public API for the HMC Kernel""" +from typing import Callable, NamedTuple, Union + +import jax +import jax.numpy as jnp +import blackjax.mcmc.integrators as integrators +import blackjax.mcmc.metrics as metrics +import blackjax.mcmc.trajectory as trajectory +from blackjax.base import SamplingAlgorithm +from blackjax.mcmc.proposal import safe_energy_diff, static_binomial_sampling +from blackjax.mcmc.trajectory import hmc_energy +from blackjax.types import ArrayLikeTree, ArrayTree, PRNGKey +from blackjax.mcmc.hmc import HMCState + +__all__ = [ + "HMCState", + "init", + "build_kernel", + "as_top_level_api", +] + +class MALTInfo(NamedTuple): + + # momentum: ArrayTree + acceptance_rate: float + is_accepted: bool + is_divergent: bool + energy: float + # proposal: integrators.IntegratorState + num_integration_steps: int + + + + +def init(position: ArrayLikeTree, logdensity_fn: Callable): + logdensity, logdensity_grad = jax.value_and_grad(logdensity_fn)(position) + return HMCState(position, logdensity, logdensity_grad) + + +def build_kernel( + integrator: Callable = integrators.velocity_verlet, + divergence_threshold: float = 1000, + L_proposal_factor = jnp.inf, +): + """Build a HMC kernel. + + Parameters + ---------- + integrator + The symplectic integrator to use to integrate the Hamiltonian dynamics. + divergence_threshold + Value of the difference in energy above which we consider that the transition is + divergent. + + Returns + ------- + A kernel that takes a rng_key and a Pytree that contains the current state + of the chain and that returns a new state of the chain along with + information about the transition. + + """ + + def kernel( + rng_key: PRNGKey, + state: HMCState, + logdensity_fn: Callable, + step_size: float, + inverse_mass_matrix: metrics.MetricTypes, + num_integration_steps: int, + + ) -> tuple[HMCState, MALTInfo]: + """Generate a new sample with the HMC kernel.""" + + L = num_integration_steps * step_size + L_proposal = L_proposal_factor * L + + # jax.debug.print("L_proposal {L_proposal}",L_proposal=L_proposal) + + key_trajectory, key_momentum, key_integrator = jax.random.split(rng_key, 3) + metric = metrics.default_metric(inverse_mass_matrix) + symplectic_integrator = lambda state, step_size, rng_key: integrators.with_maruyama(integrator(logdensity_fn, metric.kinetic_energy), metric.kinetic_energy, inverse_mass_matrix)(state, step_size, L_proposal=L_proposal, rng_key=rng_key) + proposal_generator = hmc_proposal( + symplectic_integrator, + metric.kinetic_energy, + step_size, + num_integration_steps, + divergence_threshold, + rng_key=key_trajectory, + ) + + + position, logdensity, logdensity_grad = state + momentum = metric.sample_momentum(key_momentum, position) + + integrator_state = integrators.IntegratorState( + position, momentum, logdensity, logdensity_grad + ) + proposal, info, _ = proposal_generator(key_integrator, integrator_state) + proposal = HMCState( + proposal.position, proposal.logdensity, proposal.logdensity_grad + ) + + return proposal, info + + return kernel + + +def as_top_level_api( + logdensity_fn: Callable, + step_size: float, + inverse_mass_matrix: metrics.MetricTypes, + num_integration_steps: int, + *, + divergence_threshold: int = 1000, + integrator: Callable = integrators.velocity_verlet, + L_proposal_factor = jnp.inf, +) -> SamplingAlgorithm: + """Implements the (basic) user interface for the HMC kernel. + + The general hmc kernel builder (:meth:`blackjax.mcmc.hmc.build_kernel`, alias + `blackjax.hmc.build_kernel`) can be cumbersome to manipulate. Since most users only + need to specify the kernel parameters at initialization time, we provide a helper + function that specializes the general kernel. + + We also add the general kernel and state generator as an attribute to this class so + users only need to pass `blackjax.hmc` to SMC, adaptation, etc. algorithms. + + Examples + -------- + + A new HMC kernel can be initialized and used with the following code: + + .. code:: + + hmc = blackjax.hmc( + logdensity_fn, step_size, inverse_mass_matrix, num_integration_steps + ) + state = hmc.init(position) + new_state, info = hmc.step(rng_key, state) + + Kernels are not jit-compiled by default so you will need to do it manually: + + .. code:: + + step = jax.jit(hmc.step) + new_state, info = step(rng_key, state) + + Should you need to you can always use the base kernel directly: + + .. code:: + + import blackjax.mcmc.integrators as integrators + + kernel = blackjax.hmc.build_kernel(integrators.mclachlan) + state = blackjax.hmc.init(position, logdensity_fn) + state, info = kernel( + rng_key, + state, + logdensity_fn, + step_size, + inverse_mass_matrix, + num_integration_steps, + ) + + Parameters + ---------- + logdensity_fn + The log-density function we wish to draw samples from. + step_size + The value to use for the step size in the symplectic integrator. + inverse_mass_matrix + The value to use for the inverse mass matrix when drawing a value for + the momentum and computing the kinetic energy. This argument will be + passed to the ``metrics.default_metric`` function so it supports the + full interface presented there. + num_integration_steps + The number of steps we take with the symplectic integrator at each + sample step before returning a sample. + divergence_threshold + The absolute value of the difference in energy between two states above + which we say that the transition is divergent. The default value is + commonly found in other libraries, and yet is arbitrary. + integrator + (algorithm parameter) The symplectic integrator to use to integrate the + trajectory. + + Returns + ------- + A ``SamplingAlgorithm``. + """ + + kernel = build_kernel(integrator, divergence_threshold) + + def init_fn(position: ArrayLikeTree, rng_key=None): + del rng_key + return init(position, logdensity_fn) + + def step_fn(rng_key: PRNGKey, state): + return kernel( + rng_key, + state, + logdensity_fn, + step_size, + inverse_mass_matrix, + num_integration_steps, + L_proposal_factor, + ) + + return SamplingAlgorithm(init_fn, step_fn) + + +def hmc_proposal( + integrator: Callable, + kinetic_energy: metrics.KineticEnergy, + step_size: Union[float, ArrayLikeTree], + num_integration_steps: int = 1, + divergence_threshold: float = 1000, + *, + sample_proposal: Callable = static_binomial_sampling, + rng_key: PRNGKey, +) -> Callable: + """Vanilla HMC algorithm. + + The algorithm integrates the trajectory applying a symplectic integrator + `num_integration_steps` times in one direction to get a proposal and uses a + Metropolis-Hastings acceptance step to either reject or accept this + proposal. This is what people usually refer to when they talk about "the + HMC algorithm". + + Parameters + ---------- + integrator + Symplectic integrator used to build the trajectory step by step. + kinetic_energy + Function that computes the kinetic energy. + step_size + Size of the integration step. + num_integration_steps + Number of times we run the symplectic integrator to build the trajectory + divergence_threshold + Threshold above which we say that there is a divergence. + + Returns + ------- + A kernel that generates a new chain state and information about the transition. + + """ + build_trajectory = trajectory.langevin_integration(integrator, rng_key) + hmc_energy_fn = hmc_energy(kinetic_energy) + + def generate( + rng_key, state: integrators.IntegratorState + ) -> tuple[integrators.IntegratorState, MALTInfo, ArrayTree]: + """Generate a new chain state.""" + end_state, delta_energy = build_trajectory(state, step_size, num_integration_steps) + end_state = flip_momentum(end_state) + # proposal_energy = hmc_energy_fn(state) + new_energy = hmc_energy_fn(end_state) + # delta_energy = safe_energy_diff(proposal_energy, new_energy) + + delta_energy = jnp.where(jnp.isnan(delta_energy), -jnp.inf, delta_energy) + # jax.debug.print("delta_energy_trajectory {x}",x=(delta_energy_trajectory, delta_energy)) + is_diverging = -delta_energy > divergence_threshold + # jax.debug.print("is_diverging {x}",x=is_diverging) + sampled_state, info = sample_proposal(rng_key, delta_energy, state, end_state) + do_accept, p_accept, other_proposal_info = info + # jax.debug.print("delta_energy {x}",x=delta_energy) + # jax.debug.print("p_accept {p_accept}", p_accept=(p_accept, delta_energy)) + + info = MALTInfo( + # state.momentum, + p_accept, + do_accept, + is_diverging, + new_energy, + # end_state, + num_integration_steps, + ) + + return sampled_state, info, other_proposal_info + + return generate + + +def flip_momentum( + state: integrators.IntegratorState, +) -> integrators.IntegratorState: + """Flip the momentum at the end of the trajectory. + + To guarantee time-reversibility (hence detailed balance) we + need to flip the last state's momentum. If we run the hamiltonian + dynamics starting from the last state with flipped momentum we + should indeed retrieve the initial state (with flipped momentum). + + """ + flipped_momentum = jax.tree_util.tree_map(lambda m: -1.0 * m, state.momentum) + return integrators.IntegratorState( + state.position, + flipped_momentum, + state.logdensity, + state.logdensity_grad, + ) diff --git a/blackjax/mcmc/mchmc.py b/blackjax/mcmc/mchmc.py new file mode 100644 index 000000000..06bda7097 --- /dev/null +++ b/blackjax/mcmc/mchmc.py @@ -0,0 +1,134 @@ +# Copyright 2020- The Blackjax Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Public API for the MCLMC Kernel""" +from typing import Callable, NamedTuple + +import jax +import jax.numpy as jnp + +from blackjax.base import SamplingAlgorithm +from blackjax.mcmc.integrators import ( + IntegratorState, + isokinetic_mclachlan, +) +from blackjax.types import ArrayLike, PRNGKey +from blackjax.util import generate_unit_vector, pytree_size +from blackjax.mcmc.mclmc import handle_high_energy, handle_nans, MCLMCInfo +from blackjax.mcmc.adjusted_mclmc_dynamic import make_random_trajectory_length_fn +__all__ = ["MCLMCInfo", "init", "build_kernel", "as_top_level_api"] + +class MCHMCState(NamedTuple): + position: ArrayLike + momentum: ArrayLike + logdensity: float + logdensity_grad: ArrayLike + steps_until_refresh: int + + + +def init(position: ArrayLike, logdensity_fn, random_generator_arg): + if pytree_size(position) < 2: + raise ValueError( + "The target distribution must have more than 1 dimension for MCLMC." + ) + l, g = jax.value_and_grad(logdensity_fn)(position) + + return MCHMCState( + position=position, + momentum=generate_unit_vector(random_generator_arg, position), + logdensity=l, + logdensity_grad=g, + steps_until_refresh=0, + ) + +def integrator_state(state: MCHMCState) -> IntegratorState: + return IntegratorState( + position=state.position, + momentum=state.momentum, + logdensity=state.logdensity, + logdensity_grad=state.logdensity_grad, + ) + + +def build_kernel( + # integration_steps_fn, + integrator, + desired_energy_var_max_ratio=jnp.inf, + desired_energy_var=5e-4, +): + """ + """ + + + + def kernel( + rng_key: PRNGKey, state: MCHMCState, logdensity_fn, L: float, step_size: float, inverse_mass_matrix: ArrayLike + ) -> tuple[MCHMCState, MCLMCInfo]: + step = integrator(logdensity_fn=logdensity_fn, inverse_mass_matrix=inverse_mass_matrix) + (position, momentum, logdensity, logdensitygrad), kinetic_change = step( + integrator_state(state), step_size + ) + + randomization_key, refresh_key, energy_cutoff_key, nan_key = jax.random.split(rng_key, 4) + + num_steps_per_traj = make_random_trajectory_length_fn(True)(L/step_size)(randomization_key).astype(jnp.int64) + + + + energy_change = kinetic_change - logdensity + state.logdensity + + eev_max_per_dim = desired_energy_var_max_ratio * desired_energy_var + ndims = pytree_size(position) + + momentum=(state.steps_until_refresh==0) * generate_unit_vector(refresh_key, state.position) + (state.steps_until_refresh>0) * momentum + + steps_until_refresh = (state.steps_until_refresh==0) * num_steps_per_traj + (state.steps_until_refresh>0) * (state.steps_until_refresh - 1) + + new_state, info = handle_high_energy(state, MCHMCState(position, momentum, logdensity, logdensitygrad, steps_until_refresh), MCLMCInfo( + logdensity=logdensity, + energy_change=energy_change, + kinetic_change=kinetic_change, + nonans=True + ), energy_cutoff_key, cutoff = jnp.sqrt(ndims * eev_max_per_dim)) + + new_state, info = handle_nans(state, new_state, info, nan_key) + + return new_state, info + + return kernel + + +def as_top_level_api( + logdensity_fn: Callable, + L, + step_size, + integrator=isokinetic_mclachlan, + inverse_mass_matrix=1.0, + desired_energy_var_max_ratio=jnp.inf, +) -> SamplingAlgorithm: + """ + """ + + kernel = build_kernel( + integrator, + desired_energy_var_max_ratio=desired_energy_var_max_ratio, + ) + + def init_fn(position: ArrayLike, rng_key: PRNGKey): + return init(position, logdensity_fn, rng_key) + + def update_fn(rng_key, state): + return kernel(rng_key, state, logdensity_fn, L, step_size, inverse_mass_matrix) + + return SamplingAlgorithm(init_fn, update_fn) diff --git a/blackjax/mcmc/mclmc.py b/blackjax/mcmc/mclmc.py index ff9638a1f..0b4730786 100644 --- a/blackjax/mcmc/mclmc.py +++ b/blackjax/mcmc/mclmc.py @@ -15,6 +15,8 @@ from typing import Callable, NamedTuple import jax +import jax.numpy as jnp +import time from blackjax.base import SamplingAlgorithm from blackjax.mcmc.integrators import ( @@ -24,6 +26,7 @@ ) from blackjax.types import ArrayLike, PRNGKey from blackjax.util import generate_unit_vector, pytree_size +from jax.flatten_util import ravel_pytree __all__ = ["MCLMCInfo", "init", "build_kernel", "as_top_level_api"] @@ -43,9 +46,10 @@ class MCLMCInfo(NamedTuple): logdensity: float kinetic_change: float energy_change: float + nonans: bool -def init(position: ArrayLike, logdensity_fn, rng_key): +def init(position: ArrayLike, logdensity_fn, random_generator_arg): if pytree_size(position) < 2: raise ValueError( "The target distribution must have more than 1 dimension for MCLMC." @@ -54,13 +58,18 @@ def init(position: ArrayLike, logdensity_fn, rng_key): return IntegratorState( position=position, - momentum=generate_unit_vector(rng_key, position), + momentum=generate_unit_vector(random_generator_arg, position), logdensity=l, logdensity_grad=g, ) -def build_kernel(logdensity_fn, inverse_mass_matrix, integrator): + +def build_kernel( + integrator, + desired_energy_var_max_ratio=jnp.inf, + desired_energy_var=5e-4, +): """Build a HMC kernel. Parameters @@ -80,24 +89,57 @@ def build_kernel(logdensity_fn, inverse_mass_matrix, integrator): """ - step = with_isokinetic_maruyama( - integrator(logdensity_fn=logdensity_fn, inverse_mass_matrix=inverse_mass_matrix) - ) def kernel( - rng_key: PRNGKey, state: IntegratorState, L: float, step_size: float + rng_key: PRNGKey, state: IntegratorState, logdensity_fn, L: float, step_size: float, + inverse_mass_matrix, ) -> tuple[IntegratorState, MCLMCInfo]: + # tic = time.time() + step = with_isokinetic_maruyama( + integrator(logdensity_fn=logdensity_fn, inverse_mass_matrix=inverse_mass_matrix) + ) + + # return 0, None + + # state, MCLMCInfo( + + # logdensity=state.logdensity, + # energy_change=0.0, + # kinetic_change=0.0, + # nonans=True + # ) + # raise Exception + + + # jax.debug.print("L {x}", x=L) + # jax.debug.print("step_size {x}", x=step_size) + # jax.debug.print("inverse_mass_matrix {x}", x=inverse_mass_matrix) + + kernel_key, energy_cutoff_key, nan_key = jax.random.split(rng_key, 3) + + (position, momentum, logdensity, logdensitygrad), kinetic_change = step( - state, step_size, L, rng_key + state, step_size, L, kernel_key ) - return IntegratorState( - position, momentum, logdensity, logdensitygrad - ), MCLMCInfo( + energy_change = kinetic_change - logdensity + state.logdensity + eev_max_per_dim = desired_energy_var_max_ratio * desired_energy_var + ndims = pytree_size(position) + + # jax.debug.print("kinetic_change: {x}", x=kinetic_change) + # jax.debug.print("potential energy_change: {x}", x=state.logdensity - logdensity) + + new_state, info = handle_high_energy(state, IntegratorState(position, momentum, logdensity, logdensitygrad), MCLMCInfo( logdensity=logdensity, - energy_change=kinetic_change - logdensity + state.logdensity, + energy_change=energy_change, kinetic_change=kinetic_change, - ) + nonans=True + ), energy_cutoff_key, cutoff = jnp.sqrt(ndims * eev_max_per_dim)) + + new_state, info = handle_nans(state, new_state, info, nan_key) + + # jax.debug.print("Time taken in chain: {x}", x=time.time() - tic) + return new_state, info return kernel @@ -108,6 +150,7 @@ def as_top_level_api( step_size, integrator=isokinetic_mclachlan, inverse_mass_matrix=1.0, + desired_energy_var_max_ratio=jnp.inf, ) -> SamplingAlgorithm: """The general mclmc kernel builder (:meth:`blackjax.mcmc.mclmc.build_kernel`, alias `blackjax.mclmc.build_kernel`) can be cumbersome to manipulate. Since most users only need to specify the kernel @@ -155,12 +198,60 @@ def as_top_level_api( A ``SamplingAlgorithm``. """ - kernel = build_kernel(logdensity_fn, inverse_mass_matrix, integrator) + kernel = build_kernel( + + integrator, + desired_energy_var_max_ratio=desired_energy_var_max_ratio, + ) def init_fn(position: ArrayLike, rng_key: PRNGKey): return init(position, logdensity_fn, rng_key) def update_fn(rng_key, state): - return kernel(rng_key, state, L, step_size) + return kernel(rng_key, state, logdensity_fn, L, step_size, inverse_mass_matrix) return SamplingAlgorithm(init_fn, update_fn) + + +def handle_nans( + previous_state, next_state, info, key +): + + new_momentum = generate_unit_vector(key, previous_state.position) + + nonans = jnp.logical_and(jnp.all(jnp.isfinite(next_state.position)), jnp.all(jnp.isfinite(next_state.momentum))) + + state, info = jax.lax.cond( + nonans, + lambda: (next_state, info), + lambda: (previous_state._replace( + momentum=new_momentum, + ), MCLMCInfo( + logdensity=previous_state.logdensity, + energy_change=0.0, + kinetic_change=0.0, + nonans=nonans + )), + ) + + return state, info +def handle_high_energy( + previous_state, next_state, info, key, cutoff +): + + new_momentum = generate_unit_vector(key, previous_state.position) + + state, info = jax.lax.cond( + jnp.abs(info.energy_change) > cutoff, + lambda: (previous_state._replace( + momentum=new_momentum, + ), MCLMCInfo( + logdensity=previous_state.logdensity, + energy_change=0.0, + kinetic_change=0.0, + nonans=info.nonans + )), + lambda: (next_state, info), + ) + + return state, info \ No newline at end of file diff --git a/blackjax/mcmc/nuts.py b/blackjax/mcmc/nuts.py index c75ecdec6..75399a1e7 100644 --- a/blackjax/mcmc/nuts.py +++ b/blackjax/mcmc/nuts.py @@ -120,6 +120,7 @@ def kernel( ) -> tuple[hmc.HMCState, NUTSInfo]: """Generate a new sample with the NUTS kernel.""" + metric = metrics.default_metric(inverse_mass_matrix) symplectic_integrator = integrator(logdensity_fn, metric.kinetic_energy) proposal_generator = iterative_nuts_proposal( @@ -132,7 +133,10 @@ def kernel( key_momentum, key_integrator = jax.random.split(rng_key, 2) - position, logdensity, logdensity_grad = state + # position, logdensity, logdensity_grad = state + position = state.position + logdensity = state.logdensity + logdensity_grad = state.logdensity_grad momentum = metric.sample_momentum(key_momentum, position) integrator_state = integrators.IntegratorState( @@ -142,6 +146,9 @@ def kernel( proposal = hmc.HMCState( proposal.position, proposal.logdensity, proposal.logdensity_grad ) + # jax.debug.print("step {x}",x=info.acceptance_rate) + # jax.debug.print("num steps {x}",x=info.num_integration_steps) + # jax.debug.print("step size {x}",x=step_size) return proposal, info return kernel diff --git a/blackjax/mcmc/pseudofermion.py b/blackjax/mcmc/pseudofermion.py new file mode 100644 index 000000000..2bae3f6f4 --- /dev/null +++ b/blackjax/mcmc/pseudofermion.py @@ -0,0 +1,55 @@ +from functools import partial +from typing import Any, Callable, NamedTuple + +import jax +import jax.numpy as jnp +import numpy as np + +import blackjax.mcmc.hmc as hmc +import blackjax.mcmc.integrators as integrators +import blackjax.mcmc.metrics as metrics +import blackjax.mcmc.proposal as proposal +import blackjax.mcmc.termination as termination +import blackjax.mcmc.trajectory as trajectory +from blackjax.base import SamplingAlgorithm +from blackjax.types import ArrayLikeTree, ArrayTree, PRNGKey +import blackjax + + +def build_kernel(kernel_1, kernel_2, logdensity_fn): + def kernel(state, rng_key): + next_x_state, info = kernel_1( + rng_key=rng_key, + state=state['x'], + step_size=1e-3, + inverse_mass_matrix=jnp.ones(state['x'].position.shape[0]), + num_integration_steps=1, + logdensity_fn=partial(logdensity_fn, pseudofermion=state['y']), + ) + next_y_state = kernel_2(state['y']) + return {'x': next_x_state, 'y': next_y_state}, info + return kernel + +def init(position, logdensity_fn, pseudofermion, init_1, init_2, rng_key ): + key_1, key_2 = jax.random.split(rng_key, 2) + state_b = init_1(position, partial(logdensity_fn, pseudofermion=pseudofermion) ) + state_pf = init_2(pseudofermion) + + return {'x': state_b, 'y': state_pf} + + +def as_top_level_api( + kernel_1, + kernel_2, + init_1, + init_2, + logdensity_fn: Callable, +) -> SamplingAlgorithm: + + # kernel = build_kernel(integrator, divergence_threshold) + + return None + + return SamplingAlgorithm(init_fn, step_fn) + + diff --git a/blackjax/mcmc/termination.py b/blackjax/mcmc/termination.py index eb1276da3..9fa7cee6c 100644 --- a/blackjax/mcmc/termination.py +++ b/blackjax/mcmc/termination.py @@ -33,10 +33,10 @@ def iterative_uturn_numpyro(is_turning: CheckTurning): def new_state(chain_state, max_num_doublings) -> IterativeUTurnState: flat, _ = jax.flatten_util.ravel_pytree(chain_state.position) - num_dims = jnp.shape(flat)[0] + ndims = jnp.shape(flat)[0] return IterativeUTurnState( - jnp.zeros((max_num_doublings, num_dims)), - jnp.zeros((max_num_doublings, num_dims)), + jnp.zeros((max_num_doublings, ndims)), + jnp.zeros((max_num_doublings, ndims)), 0, 0, ) diff --git a/blackjax/mcmc/trajectory.py b/blackjax/mcmc/trajectory.py index 7bb1b35a5..25260e777 100644 --- a/blackjax/mcmc/trajectory.py +++ b/blackjax/mcmc/trajectory.py @@ -127,6 +127,34 @@ def one_step(_, state): return integrate +def langevin_integration( + integrator: Callable, + rng_key: PRNGKey, + direction: int = 1, +) -> Callable: + """Generate a trajectory by integrating several times in one direction.""" + + def integrate( + initial_state: IntegratorState, step_size, num_integration_steps + ) -> IntegratorState: + directed_step_size = jax.tree_util.tree_map( + lambda step_size: direction * step_size, step_size + ) + + # jax.debug.print("num_integration_steps {x}", x=num_integration_steps) + + def one_step(_, accum): + state, delta_energy, rng_key = accum + rng_key, key2 = jax.random.split(rng_key) + new_state, (_, delta_energy_new) = integrator(state, directed_step_size, rng_key) + # jax.debug.print("delta_energy 0 {x}", x=delta_energy_new) + return (new_state, delta_energy+delta_energy_new, key2) + + state, delta_energy, _ = jax.lax.fori_loop(0, num_integration_steps, one_step, (initial_state, 0.0, rng_key)) + return state, -delta_energy + + return integrate + class DynamicIntegrationState(NamedTuple): step: int diff --git a/blackjax/mcmc/uhmc.py b/blackjax/mcmc/uhmc.py new file mode 100644 index 000000000..4e6f6daea --- /dev/null +++ b/blackjax/mcmc/uhmc.py @@ -0,0 +1,161 @@ +# Copyright 2020- The Blackjax Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Public API for the Underdamped Langevin Kernel""" +from typing import Callable, NamedTuple + +import jax +from blackjax.mcmc.adjusted_mclmc_dynamic import make_random_trajectory_length_fn +from blackjax.base import SamplingAlgorithm +from blackjax.mcmc.integrators import ( + IntegratorState, + velocity_verlet, +) +from blackjax.types import ArrayLike, PRNGKey +import blackjax.mcmc.metrics as metrics +import jax.numpy as jnp +from blackjax.util import pytree_size, generate_unit_vector +from blackjax.mcmc.underdamped_langevin import handle_high_energy, handle_nans, LangevinInfo +__all__ = ["LangevinInfo", "init", "build_kernel", "as_top_level_api"] + +class UHMCState(NamedTuple): + position: ArrayLike + momentum: ArrayLike + logdensity: float + logdensity_grad: ArrayLike + steps_until_refresh: int + +def integrator_state(state: UHMCState) -> IntegratorState: + return IntegratorState( + position=state.position, + momentum=state.momentum, + logdensity=state.logdensity, + logdensity_grad=state.logdensity_grad, + ) + + +def init(position: ArrayLike, logdensity_fn, random_generator_arg): + + l, g = jax.value_and_grad(logdensity_fn)(position) + + metric = metrics.default_metric(jnp.ones_like(position)) + + return UHMCState( + position=position, + momentum = metric.sample_momentum(random_generator_arg, position), + logdensity=l, + logdensity_grad=g, + steps_until_refresh=0, + ) + + +def build_kernel( + integrator, + desired_energy_var_max_ratio=1e3, + desired_energy_var=5e-4,): + """Build a HMC kernel. + + Parameters + ---------- + integrator + The symplectic integrator to use to integrate the Langevin dynamics. + L + the momentum decoherence rate. + step_size + step size of the integrator. + + Returns + ------- + A kernel that takes a rng_key and a Pytree that contains the current state + of the chain and that returns a new state of the chain along with + information about the transition. + + """ + + + def kernel( + rng_key: PRNGKey, state: UHMCState, logdensity_fn, L: float, step_size: float, inverse_mass_matrix, + ) -> tuple[UHMCState, LangevinInfo]: + metric = metrics.default_metric(inverse_mass_matrix) + step = integrator(logdensity_fn, metric.kinetic_energy) + + refresh_key, energy_cutoff_key, nan_key, randomization_key = jax.random.split(rng_key, 4) + + (position, momentum, logdensity, logdensitygrad) = step( + integrator_state(state), step_size + ) + + kinetic_change = - metric.kinetic_energy(state.momentum) + metric.kinetic_energy(momentum) + energy_change = kinetic_change - logdensity + state.logdensity + + num_steps_per_traj = make_random_trajectory_length_fn(True)(L/step_size)(randomization_key).astype(jnp.int64) + + momentum = (state.steps_until_refresh==0) * metric.sample_momentum(refresh_key, position) + (state.steps_until_refresh>0) * momentum + + steps_until_refresh = (state.steps_until_refresh==0) * num_steps_per_traj + (state.steps_until_refresh>0) * (state.steps_until_refresh - 1) + + eev_max_per_dim = desired_energy_var_max_ratio * desired_energy_var + ndims = pytree_size(position) + + + + new_state, info = handle_high_energy(state, UHMCState(position, momentum, logdensity, logdensitygrad, steps_until_refresh), LangevinInfo( + logdensity=logdensity, + energy_change=energy_change, + kinetic_change=kinetic_change, + nonans=True + ), energy_cutoff_key, cutoff = jnp.sqrt(ndims * eev_max_per_dim), inverse_mass_matrix=inverse_mass_matrix) + + new_state, info = handle_nans(state, new_state, info, nan_key, inverse_mass_matrix) + return new_state, info + + return kernel + + +def as_top_level_api( + logdensity_fn: Callable, + L, + step_size, + integrator=velocity_verlet, + inverse_mass_matrix=1.0, + desired_energy_var_max_ratio=jnp.inf, + desired_energy_var=5e-4, +) -> SamplingAlgorithm: + """The general Langevin kernel builder (:meth:`blackjax.mcmc.langevin.build_kernel`, alias `blackjax.langevin.build_kernel`) can be + cumbersome to manipulate. Since most users only need to specify the kernel + parameters at initialization time, we provide a helper function that + specializes the general kernel. + + We also add the general kernel and state generator as an attribute to this class so + users only need to pass `blackjax.langevin` to SMC, adaptation, etc. algorithms. + + + + """ + + kernel = build_kernel( + integrator, + desired_energy_var_max_ratio=desired_energy_var_max_ratio, + desired_energy_var=desired_energy_var, + ) + # metric = metrics.default_metric(inverse_mass_matrix) + + def init_fn(position: ArrayLike, rng_key: PRNGKey): + return init(position, logdensity_fn, rng_key) + + def update_fn(rng_key, state): + return kernel(rng_key, state, logdensity_fn, L, step_size, inverse_mass_matrix) + + return SamplingAlgorithm(init_fn, update_fn) + + diff --git a/blackjax/mcmc/underdamped_langevin.py b/blackjax/mcmc/underdamped_langevin.py new file mode 100644 index 000000000..6bf01591a --- /dev/null +++ b/blackjax/mcmc/underdamped_langevin.py @@ -0,0 +1,203 @@ +# Copyright 2020- The Blackjax Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Public API for the Underdamped Langevin Kernel""" +from typing import Callable, NamedTuple + +import jax + +from blackjax.base import SamplingAlgorithm +from blackjax.mcmc.integrators import ( + IntegratorState, + with_maruyama, + velocity_verlet, +) +from blackjax.types import ArrayLike, PRNGKey +import blackjax.mcmc.metrics as metrics +import jax.numpy as jnp +from blackjax.util import pytree_size +from blackjax.adaptation.mclmc_adaptation import handle_high_energy +__all__ = ["LangevinInfo", "init", "build_kernel", "as_top_level_api"] + + +class LangevinInfo(NamedTuple): + """ + Additional information on the Langevin transition. + + logdensity + The log-density of the distribution at the current step of the Langevin chain. + kinetic_change + The difference in kinetic energy between the current and previous step. + energy_change + The difference in energy between the current and previous step. + """ + + logdensity: float + kinetic_change: float + energy_change: float + nonans : bool + +def init(position: ArrayLike, logdensity_fn, random_generator_arg): + + l, g = jax.value_and_grad(logdensity_fn)(position) + + metric = metrics.default_metric(jnp.ones_like(position)) + + return IntegratorState( + position=position, + momentum = metric.sample_momentum(random_generator_arg, position), + logdensity=l, + logdensity_grad=g, + ) + + +def build_kernel( + integrator, + desired_energy_var_max_ratio=1e3, + desired_energy_var=5e-4,): + """Build a HMC kernel. + + Parameters + ---------- + integrator + The symplectic integrator to use to integrate the Langevin dynamics. + L + the momentum decoherence rate. + step_size + step size of the integrator. + + Returns + ------- + A kernel that takes a rng_key and a Pytree that contains the current state + of the chain and that returns a new state of the chain along with + information about the transition. + + """ + + + def kernel( + rng_key: PRNGKey, state: IntegratorState, logdensity_fn, L: float, step_size: float, inverse_mass_matrix, + ) -> tuple[IntegratorState, LangevinInfo]: + metric = metrics.default_metric(inverse_mass_matrix) + step = with_maruyama(integrator(logdensity_fn, metric.kinetic_energy), metric.kinetic_energy,inverse_mass_matrix) + + (position, momentum, logdensity, logdensitygrad), (kinetic_change, energy_error) = step( + state, step_size, L, rng_key + ) + + + eev_max_per_dim = desired_energy_var_max_ratio * desired_energy_var + ndims = pytree_size(position) + + energy_key, nan_key = jax.random.split(rng_key) + + new_state, info = handle_high_energy( + previous_state=state, + next_state=IntegratorState(position, momentum, logdensity, logdensitygrad), + info=LangevinInfo( + logdensity=logdensity, + energy_change=energy_error, + kinetic_change=kinetic_change, + nonans=True + ), + key=energy_key, + inverse_mass_matrix=inverse_mass_matrix, + cutoff=jnp.sqrt(ndims * eev_max_per_dim), + ) + + new_state, info = handle_nans(state, new_state, info, nan_key, inverse_mass_matrix) + return new_state, info + + + return kernel + + +def as_top_level_api( + logdensity_fn: Callable, + L, + step_size, + integrator=velocity_verlet, + inverse_mass_matrix=1.0, + desired_energy_var_max_ratio=jnp.inf, + desired_energy_var=5e-4, +) -> SamplingAlgorithm: + """The general Langevin kernel builder (:meth:`blackjax.mcmc.langevin.build_kernel`, alias `blackjax.langevin.build_kernel`) can be + cumbersome to manipulate. Since most users only need to specify the kernel + parameters at initialization time, we provide a helper function that + specializes the general kernel. + + We also add the general kernel and state generator as an attribute to this class so + users only need to pass `blackjax.langevin` to SMC, adaptation, etc. algorithms. + """ + + kernel = build_kernel( + integrator, + desired_energy_var_max_ratio=desired_energy_var_max_ratio, + desired_energy_var=desired_energy_var, + ) + + def init_fn(position: ArrayLike, rng_key: PRNGKey): + return init(position, logdensity_fn, rng_key) + + def update_fn(rng_key, state): + return kernel( + rng_key=rng_key, state=state, logdensity_fn=logdensity_fn, L=L, step_size=step_size, inverse_mass_matrix=inverse_mass_matrix) + + return SamplingAlgorithm(init_fn, update_fn) + + +def handle_nans( + previous_state, next_state, info, key, inverse_mass_matrix +): + + metric = metrics.default_metric(inverse_mass_matrix) + new_momentum = metric.sample_momentum(key, previous_state.position) + + nonans = jnp.logical_and(jnp.all(jnp.isfinite(next_state.position)), jnp.all(jnp.isfinite(next_state.momentum))) + + state, info = jax.lax.cond( + nonans, + lambda: (next_state, info), + lambda: (previous_state._replace( + momentum=new_momentum, + ), LangevinInfo( + logdensity=previous_state.logdensity, + energy_change=0.0, + kinetic_change=0.0, + nonans=nonans + )), + ) + + return state, info + +def handle_high_energy( + previous_state, next_state, info, key, cutoff, inverse_mass_matrix +): + + metric = metrics.default_metric(inverse_mass_matrix) + new_momentum = metric.sample_momentum(key, previous_state.position) + + state, info = jax.lax.cond( + jnp.abs(info.energy_change) > cutoff, + lambda: (previous_state._replace( + momentum=new_momentum, + ), LangevinInfo( + logdensity=previous_state.logdensity, + energy_change=0.0, + kinetic_change=0.0, + nonans=False + )), + lambda: (next_state, info), + ) + + return state, info \ No newline at end of file diff --git a/blackjax/smc/tuning/from_kernel_info.py b/blackjax/smc/tuning/from_kernel_info.py index fa2c7054c..13db64a37 100644 --- a/blackjax/smc/tuning/from_kernel_info.py +++ b/blackjax/smc/tuning/from_kernel_info.py @@ -3,6 +3,7 @@ strategies to tune the parameters of mcmc kernels used within smc, based on MCMC states """ + import jax import jax.numpy as jnp diff --git a/blackjax/smc/tuning/from_particles.py b/blackjax/smc/tuning/from_particles.py index 505e7f3a1..74c4e67ef 100755 --- a/blackjax/smc/tuning/from_particles.py +++ b/blackjax/smc/tuning/from_particles.py @@ -2,6 +2,7 @@ static (all particles get the same value) strategies to tune the parameters of mcmc kernels used within SMC, based on particles. """ + import jax import jax.numpy as jnp from jax._src.flatten_util import ravel_pytree diff --git a/blackjax/util.py b/blackjax/util.py index 8cdcd45ee..b8a00f9d6 100644 --- a/blackjax/util.py +++ b/blackjax/util.py @@ -4,15 +4,19 @@ from typing import Callable, Union import jax.numpy as jnp -from jax import jit, lax +from jax import device_put, jit, lax, vmap +from jax.experimental.shard_map import shard_map from jax.flatten_util import ravel_pytree from jax.random import normal, split +from jax.sharding import NamedSharding, PartitionSpec from jax.tree_util import tree_leaves, tree_map from blackjax.base import SamplingAlgorithm, VIAlgorithm from blackjax.progress_bar import gen_scan_fn from blackjax.types import Array, ArrayLikeTree, ArrayTree, PRNGKey - +from blackjax.diagnostics import splitR +import time +import jax @partial(jit, static_argnames=("precision",), inline=True) def linear_map(diag_or_dense_a, b, *, precision="highest"): @@ -196,6 +200,7 @@ def run_inference_algorithm( keys = split(rng_key, num_steps) + def one_step(state, xs): _, rng_key = xs state, info = inference_algorithm.step(rng_key, state) @@ -204,7 +209,9 @@ def one_step(state, xs): scan_fn = gen_scan_fn(num_steps, progress_bar) xs = jnp.arange(num_steps), keys + # tic = time.time() final_state, history = scan_fn(one_step, initial_state, xs) + # toc = time.time() return final_state, history @@ -314,3 +321,312 @@ def incremental_value_update( ) total += weight return total, average + + +def eca_step( + kernel, summary_statistics_fn, adaptation_update, num_chains, superchain_size = None, ensemble_info=None +): + """ + Construct a single step of ensemble chain adaptation (eca) to be performed in parallel on multiple devices. + """ + + def step(state_all, xs): + """This function operates on a single device.""" + ( + state, + adaptation_state, + ) = state_all # state is an array of states, one for each chain on this device. adaptation_state is the same for all chains, so it is not an array. + ( + _, + keys_sampling, + key_adaptation, + ) = xs # keys_sampling.shape = (chains_per_device, ) + + # update the state of all chains on this device + state, info = vmap(kernel, (0, 0, None))(keys_sampling, state, adaptation_state) + + # combine all the chains to compute expectation values + theta = vmap(summary_statistics_fn, (0, 0, None))(state, info, key_adaptation) + Etheta = tree_map( + lambda theta: lax.psum(jnp.sum(theta, axis=0), axis_name="chains") + / num_chains, + theta, + ) + + # use these to adapt the hyperparameters of the dynamics + adaptation_state, info_to_be_stored = adaptation_update( + adaptation_state, Etheta + ) + + return (state, adaptation_state), info_to_be_stored + + + return add_ensemble_info(add_splitR(step, num_chains, superchain_size), ensemble_info) + + +def add_splitR(step, num_chains, superchain_size): + + + def _step_with_R(state_all, xs): + + state_all, info_to_be_stored = step(state_all, xs) + + state, adaptation_state = state_all + + R = splitR(state.position, num_chains, superchain_size) + split_bavg = jnp.average(jnp.square(R) - 1) + split_bmax = jnp.max(jnp.square(R) - 1) + + info_to_be_stored['R_avg'] = split_bavg + info_to_be_stored['R_max'] = split_bmax + + return (state, adaptation_state), info_to_be_stored + + def _step_with_R_1(state_all, xs): + + state_all, info_to_be_stored = step(state_all, xs) + + info_to_be_stored['R_avg'] = 0. + info_to_be_stored['R_max'] = 0. + + return state_all, info_to_be_stored + + if superchain_size == None: + return step + + if superchain_size == 1: + return _step_with_R_1 + + else: + return _step_with_R + + +def add_ensemble_info(step, ensemble_info): + + def _step(state_all, xs): + (state, adaptation_state), info_to_be_stored = step(state_all, xs) + return (state, adaptation_state), (info_to_be_stored, vmap(ensemble_info)(state.position)) + + return _step if ensemble_info is not None else step + + + +def run_eca( + rng_key, + initial_state, + kernel, + adaptation, + num_steps, + num_chains, + mesh, + superchain_size= None, + ensemble_info=None, + early_stop=False, +): + """ + Run ensemble chain adaptation (eca) in parallel on multiple devices. + ----------------------------------------------------- + Args: + rng_key: random key + initial_state: initial state of the system + kernel: kernel for the dynamics + adaptation: adaptation object + num_steps: number of steps to run + num_chains: number of chains + mesh: mesh for parallelization + ensemble_info: function that takes the state of the system and returns some information about the ensemble + early_stop: whether to stop early + Returns: + final_state: final state of the system + final_adaptation_state: final adaptation state + info_history: history of the information that was stored at each step (if early_stop is False, then this is None) + """ + + step = eca_step( + kernel, + adaptation.summary_statistics_fn, + adaptation.update, + num_chains, + superchain_size= superchain_size, + ensemble_info = ensemble_info, + ) + + def all_steps(initial_state, keys_sampling, keys_adaptation): + """This function operates on a single device. key is a random key for this device.""" + + initial_state_all = (initial_state, adaptation.initial_state) + + # run sampling + xs = ( + jnp.arange(num_steps), + keys_sampling.T, + keys_adaptation, + ) # keys for all steps that will be performed. keys_sampling.shape = (num_steps, chains_per_device), keys_adaptation.shape = (num_steps, ) + + EEVPD = jnp.zeros((num_steps,)) + EEVPD_wanted = jnp.zeros((num_steps,)) + L = jnp.zeros((num_steps,)) + entropy = jnp.zeros((num_steps,)) + equi_diag = jnp.zeros((num_steps,)) + equi_full = jnp.zeros((num_steps,)) + bias0 = jnp.zeros((num_steps,)) + bias1 = jnp.zeros((num_steps,)) + observables = jnp.zeros((num_steps,)) + r_avg = jnp.zeros((num_steps,)) + r_max = jnp.zeros((num_steps,)) + R_avg = jnp.zeros((num_steps,)) + R_max = jnp.zeros((num_steps,)) + step_size = jnp.zeros((num_steps,)) + + def step_while(a): + x, i, _, EEVPD, EEVPD_wanted, L, entropy, equi_diag, equi_full, bias0, bias1, observables, r_avg, r_max, R_avg, R_max, step_size = a + + auxilliary_input = (xs[0][i], xs[1][i], xs[2][i]) + + output, (info, pos) = step(x, auxilliary_input) + new_EEVPD = EEVPD.at[i].set(info.get("EEVPD")) + new_EEVPD_wanted = EEVPD_wanted.at[i].set(info.get("EEVPD_wanted")) + new_L = L.at[i].set(info.get("L")) + new_entropy = entropy.at[i].set(info.get("entropy")) + new_equi_diag = equi_diag.at[i].set(info.get("equi_diag")) + new_equi_full = equi_full.at[i].set(info.get("equi_full")) + new_bias0 = bias0.at[i].set(info.get("bias")[0]) + new_bias1 = bias1.at[i].set(info.get("bias")[1]) + new_observables = observables.at[i].set(info.get("observables")) + new_r_avg = r_avg.at[i].set(info.get("r_avg")) + new_r_max = r_max.at[i].set(info.get("r_max")) + new_R_avg = R_avg.at[i].set(info.get("R_avg")) + new_R_max = R_max.at[i].set(info.get("R_max")) + new_step_size = step_size.at[i].set(info.get("step_size")) + + return (output, i + 1, + (info.get("r_max") > adaptation.r_end) | (i < adaptation.save_num), # while is run while this is True + new_EEVPD, new_EEVPD_wanted, new_L, new_entropy, new_equi_diag, new_equi_full, new_bias0, new_bias1, new_observables, new_r_avg, new_r_max, new_R_avg, new_R_max, new_step_size) + + if early_stop: + final_state_all, i, _, EEVPD, EEVPD_wanted, L, entropy, equi_diag, equi_full, bias0, bias1, observables, r_avg, r_max, R_avg, R_max, step_size = lax.while_loop( + lambda a: ((a[1] < num_steps) & a[2]), + step_while, + (initial_state_all, 0, True, EEVPD, EEVPD_wanted, L, entropy, equi_diag, equi_full, bias0, bias1, observables, r_avg, r_max, R_avg, R_max, step_size), + ) + steps_done = i + info_history = { + "EEVPD": EEVPD, + "EEVPD_wanted": EEVPD_wanted, + "L": L, + "entropy": entropy, + "equi_diag": equi_diag, + "equi_full": equi_full, + "bias0": bias0, + "bias1": bias1, + "observables": observables, + "r_avg": r_avg, + "r_max": r_max, + "R_avg": R_avg, + "R_max": R_max, + "step_size": step_size, + "steps_done": steps_done, + } + + else: + final_state_all, info_history = lax.scan(step, initial_state_all, xs) + steps_done = num_steps + + final_state, final_adaptation_state = final_state_all + return ( + final_state, + final_adaptation_state, + info_history, + steps_done, + ) # info history is composed of averages over all chains, so it is a couple of scalars + + p, pscalar = PartitionSpec("chains"), PartitionSpec() + parallel_execute = shard_map( + all_steps, + mesh=mesh, + in_specs=(p, p, pscalar), + out_specs=(p, pscalar, pscalar, pscalar), + check_rep=False, + ) + + # produce all random keys that will be needed + + key_sampling, key_adaptation = split(rng_key) + num_steps = jnp.array(num_steps).item() + keys_adaptation = split(key_adaptation, num_steps) + distribute_keys = lambda key, shape: device_put( + split(key, shape), NamedSharding(mesh, p) + ) # random keys, distributed across devices + keys_sampling = distribute_keys(key_sampling, (num_chains, num_steps)) + + # run sampling in parallel + final_state, final_adaptation_state, info_history, steps_done = parallel_execute( + initial_state, keys_sampling, keys_adaptation + ) + + return final_state, final_adaptation_state, info_history, steps_done + + +def ensemble_execute_fn( + func, + rng_key, + num_chains, + mesh, + x=None, + args=None, + summary_statistics_fn=lambda y: 0.0, + superchain_size = None +): + """Given a sequential function + func(rng_key, x, args) = y, + evaluate it with an ensemble and also compute some summary statistics E[theta(y)], where expectation is taken over ensemble. + Args: + x: array distributed over all decvices + args: additional arguments for func, not distributed. + summary_statistics_fn: operates on a single member of ensemble and returns some summary statistics. + rng_key: a single random key, which will then be split, such that each member of an ensemble will get a different random key. + + Returns: + y: array distributed over all decvices. Need not be of the same shape as x. + Etheta: expected values of the summary statistics + """ + p, pscalar = PartitionSpec("chains"), PartitionSpec() + + if x is None: + X = device_put(jnp.zeros(num_chains), NamedSharding(mesh, p)) + else: + X = x + + adaptation_update = lambda _, Etheta: (Etheta, None) + + _F = eca_step( + func, + lambda y, info, key: summary_statistics_fn(y), + adaptation_update, + num_chains, + ) + + def F(x, keys): + """This function operates on a single device. key is a random key for this device.""" + y, summary_statistics = _F((x, args), (None, keys, None))[0] + return y, summary_statistics + + parallel_execute = shard_map( + F, mesh=mesh, in_specs=(p, p), out_specs=(p, pscalar), check_rep=False + ) + + if superchain_size == 1: + _keys = split(rng_key, num_chains) + + else: + _keys = jnp.repeat(split(rng_key, num_chains // superchain_size), superchain_size) + + + keys = device_put(_keys, NamedSharding(mesh, p)) # random keys, distributed across devices + + # apply F in parallel + return parallel_execute(X, keys) + + + + diff --git a/tests/adaptation/test_mass_matrix.py b/tests/adaptation/test_mass_matrix.py index 622b2111c..97d6ea882 100644 --- a/tests/adaptation/test_mass_matrix.py +++ b/tests/adaptation/test_mass_matrix.py @@ -1,4 +1,5 @@ """Test the welford adaptation algorithm.""" + import itertools import chex diff --git a/tests/mcmc/test_sampling.py b/tests/mcmc/test_sampling.py index 4d8a9fa61..d2cbd1501 100644 --- a/tests/mcmc/test_sampling.py +++ b/tests/mcmc/test_sampling.py @@ -5,6 +5,8 @@ import chex import jax + +# jax.config.update("jax_traceback_filtering", "off") import jax.numpy as jnp import jax.scipy.stats as stats import numpy as np @@ -15,6 +17,7 @@ import blackjax.diagnostics as diagnostics import blackjax.mcmc.random_walk from blackjax.adaptation.base import get_filter_adapt_info_fn, return_all_adapt_info +from blackjax.adaptation.ensemble_mclmc import emaus from blackjax.mcmc.adjusted_mclmc_dynamic import rescale from blackjax.mcmc.integrators import isokinetic_mclachlan from blackjax.util import run_inference_algorithm @@ -289,6 +292,43 @@ def run_adjusted_mclmc_static( return out + def run_emaus( + self, + sample_init, + logdensity_fn, + ndims, + key, + diagonal_preconditioning, + ): + mesh = jax.sharding.Mesh(devices=jax.devices(), axis_names="chains") + + from blackjax.mcmc.integrators import mclachlan_coefficients + + integrator_coefficients = mclachlan_coefficients + + info, grads_per_step, _acc_prob, final_state = emaus( + logdensity_fn=logdensity_fn, + sample_init=sample_init, + ndims=ndims, + num_steps1=100, + num_steps2=300, + num_chains=800, + mesh=mesh, + rng_key=key, + alpha=1.9, + C=0.1, + early_stop=1, + r_end=1e-2, + diagonal_preconditioning=diagonal_preconditioning, + integrator_coefficients=integrator_coefficients, + steps_per_sample=15, + acc_prob=None, + ensemble_observables=lambda x: x, + # ensemble_observables = lambda x: vec @ x + ) # run the algorithm + + return final_state.position + @parameterized.parameters( itertools.product( regression_test_cases, [True, False], window_adaptation_filters @@ -535,6 +575,43 @@ def get_inverse_mass_matrix(): < 0.1 ) + def test_emaus( + self, + ): + """Test the MCLMC kernel.""" + + init_key0, init_key1, inference_key = jax.random.split(self.key, 3) + + x_data = jax.random.normal(init_key0, shape=(1000, 1)) + y_data = 3 * x_data + jax.random.normal(init_key1, shape=x_data.shape) + + logposterior_fn_ = functools.partial( + self.regression_logprob, x=x_data, preds=y_data + ) + logdensity_fn = lambda x: logposterior_fn_( + coefs=x["coefs"][0], log_scale=x["log_scale"][0] + ) + + def sample_init(key): + key1, key2 = jax.random.split(key) + coefs = jax.random.uniform(key1, shape=(1,), minval=1, maxval=2) + log_scale = jax.random.uniform(key2, shape=(1,), minval=1, maxval=2) + return {"coefs": coefs, "log_scale": log_scale} + + samples = self.run_emaus( + sample_init=sample_init, + logdensity_fn=logdensity_fn, + ndims=2, + key=inference_key, + diagonal_preconditioning=True, + ) + + coefs_samples = samples["coefs"] + scale_samples = np.exp(samples["log_scale"]) + + np.testing.assert_allclose(np.mean(scale_samples), 1.0, atol=1e-1) + np.testing.assert_allclose(np.mean(coefs_samples), 3.0, atol=1e-1) + @parameterized.parameters(regression_test_cases) def test_pathfinder_adaptation( self, diff --git a/tests/mcmc/test_trajectory.py b/tests/mcmc/test_trajectory.py index e93280400..bc8490b19 100644 --- a/tests/mcmc/test_trajectory.py +++ b/tests/mcmc/test_trajectory.py @@ -1,4 +1,5 @@ """Test the trajectory integration""" + import chex import jax import jax.numpy as jnp diff --git a/tests/mcmc/test_uturn.py b/tests/mcmc/test_uturn.py index 7f9f597d6..ff1f261f6 100644 --- a/tests/mcmc/test_uturn.py +++ b/tests/mcmc/test_uturn.py @@ -1,4 +1,5 @@ """Test the iterative u-turn criterion.""" + import chex import jax.numpy as jnp from absl.testing import absltest, parameterized diff --git a/tests/optimizers/test_optimizers.py b/tests/optimizers/test_optimizers.py index a7549842f..47f437af2 100644 --- a/tests/optimizers/test_optimizers.py +++ b/tests/optimizers/test_optimizers.py @@ -1,4 +1,5 @@ """Test optimizers.""" + import functools import chex diff --git a/tests/optimizers/test_pathfinder.py b/tests/optimizers/test_pathfinder.py index b9b9c69be..f40e79410 100644 --- a/tests/optimizers/test_pathfinder.py +++ b/tests/optimizers/test_pathfinder.py @@ -1,4 +1,5 @@ """Test the pathfinder algorithm.""" + import functools import chex diff --git a/tests/smc/test_resampling.py b/tests/smc/test_resampling.py index 20cb0d813..e6570f8f6 100644 --- a/tests/smc/test_resampling.py +++ b/tests/smc/test_resampling.py @@ -1,4 +1,5 @@ """Test the resampling functions for SMC.""" + import itertools import chex diff --git a/tests/smc/test_smc.py b/tests/smc/test_smc.py index 769078c8d..7ab6350ec 100644 --- a/tests/smc/test_smc.py +++ b/tests/smc/test_smc.py @@ -1,4 +1,5 @@ """Test the generic SMC sampler""" + import functools import chex diff --git a/tests/smc/test_smc_ess.py b/tests/smc/test_smc_ess.py index 570d392d9..1f02b8d61 100644 --- a/tests/smc/test_smc_ess.py +++ b/tests/smc/test_smc_ess.py @@ -1,4 +1,5 @@ """Test the ess function""" + import functools import chex diff --git a/tests/smc/test_solver.py b/tests/smc/test_solver.py index 49db84129..8bcdd6a07 100644 --- a/tests/smc/test_solver.py +++ b/tests/smc/test_solver.py @@ -1,4 +1,5 @@ """Test the solving functions""" + import itertools import chex diff --git a/tests/smc/test_tempered_smc.py b/tests/smc/test_tempered_smc.py index 527457d62..ef8b8cb08 100644 --- a/tests/smc/test_tempered_smc.py +++ b/tests/smc/test_tempered_smc.py @@ -1,4 +1,5 @@ """Test the tempered SMC steps and routine""" + import functools import chex @@ -79,9 +80,11 @@ def logprior_fn(x): base_params, jax.tree.map(lambda x: jnp.repeat(x, num_particles, axis=0), base_params), jax.tree_util.tree_map_with_path( - lambda path, x: jnp.repeat(x, num_particles, axis=0) - if path[0].key == "step_size" - else x, + lambda path, x: ( + jnp.repeat(x, num_particles, axis=0) + if path[0].key == "step_size" + else x + ), base_params, ), ] diff --git a/tests/test_benchmarks.py b/tests/test_benchmarks.py index 2d108a48d..ea9c6aa66 100644 --- a/tests/test_benchmarks.py +++ b/tests/test_benchmarks.py @@ -5,6 +5,7 @@ obviously more models. It should also be run in CI. """ + import functools import jax diff --git a/tests/test_compilation.py b/tests/test_compilation.py index 7179b71ba..2d3b03a44 100644 --- a/tests/test_compilation.py +++ b/tests/test_compilation.py @@ -5,6 +5,7 @@ internal changes do not trigger more compilations than is necessary. """ + import chex import jax import jax.numpy as jnp diff --git a/tests/test_diagnostics.py b/tests/test_diagnostics.py index b583c8645..1d7c74846 100644 --- a/tests/test_diagnostics.py +++ b/tests/test_diagnostics.py @@ -1,4 +1,5 @@ """Test MCMC diagnostics.""" + import functools import itertools diff --git a/velocity_verlet_gaussian.ipynb b/velocity_verlet_gaussian.ipynb new file mode 100644 index 000000000..cff0442a8 --- /dev/null +++ b/velocity_verlet_gaussian.ipynb @@ -0,0 +1,429 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Velocity Verlet Integrator for a Gaussian Target\n", + "\n", + "This notebook demonstrates how to use the velocity verlet integrator from Blackjax to simulate Hamiltonian dynamics for a Gaussian target distribution." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "WARNING:2025-04-22 11:29:00,948:jax._src.xla_bridge:909: An NVIDIA GPU may be present on this machine, but a CUDA-enabled jaxlib is not installed. Falling back to cpu.\n" + ] + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "\n", + "import jax\n", + "import jax.numpy as jnp\n", + "import jax.scipy.stats as stats\n", + "\n", + "import blackjax\n", + "from blackjax.mcmc import integrators\n", + "from blackjax.mcmc import metrics\n", + "from blackjax.types import ArrayTree\n", + "\n", + "# Set random seed for reproducibility\n", + "rng_key = jax.random.key(42)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Define a Gaussian Target Distribution\n", + "\n", + "We'll use a 2D Gaussian distribution as our target. The log-density function is defined as:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAzwAAAK7CAYAAAA3NIo6AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzs3XV4VEcXwOFf3B1ICIQkOAnu7u4UK1ac4u6uxQuUFiilWHF3d3eHoBECcXfbvd8fafM1hZYkROG8z5MHuHvvzNnNkszZmXtGQ1EUBSGEEEIIIYT4AmlmdQBCCCGEEEIIkVEk4RFCCCGEEEJ8sSThEUIIIYQQQnyxJOERQgghhBBCfLEk4RFCCCGEEEJ8sSThEUIIIYQQQnyxJOERQgghhBBCfLEk4RFCCCGEEEJ8sSThEUIIIYQQQnyxJOERIgc6d+4cffr0oXjx4hgZGZEvXz7atGnD3bt3Pzi3bt26aGhooKGhgaamJiYmJhQuXJiOHTuyZ88e1Gp1qvo+cuQIbdq0wdbWFl1dXUxMTChXrhwzZszg7du36fUUM9TMmTPR0NDI1D43btyY9H34ry8HB4dMjSsltm3bxvLly1N8flrecw4ODvTq1StVcV27do2ZM2cSEhKSquv+2deFCxfQ0NBgz549qWrnv0RFRTFz5kwuXLjwwWN/vRfc3d3TrT8hhBD/TjurAxBCpN7q1asJDAxkxIgRODk54e/vz9KlS6latSonT56kfv36yc4vWLAgW7duBSAyMhI3NzcOHDhAx44dqVWrFocPH8bMzOw/+1Sr1fTu3ZvNmzfTrFkz5s+fj4ODA9HR0dy+fZsNGzawfv16PD09M+x5p5d+/frRtGnTTO2zRYsWXL9+PdmxatWq0aFDB8aMGZN0TE9PL1PjSolt27bx5MkTRo4cmeJrUvue279/P6ampqmK69q1a8yaNYtevXphbm6e4uvS0ldqRUVFMWvWLCAxAfy7v94LefPmzdAYhBBCJJKER4gc6JdffiFPnjzJjjVt2pTChQvzww8/fJDwGBgYULVq1WTH+vXrx4YNG+jTpw8DBgxg586d/9nnwoUL2bx5M/Pnz2fixIkf9D1p0iR+/fXXz3hWmSd//vzkz58/U/vMnTs3uXPn/uC4tbX1B9+btFCpVCQkJGSbhCm177ly5cpleEzR0dEYGBhkSl//5d/eC0IIITKGLGkTIgf6Z7IDYGxsjJOTU6pmWHr37k3z5s3ZvXs3Hh4e/3peXFwcixYtomTJkh8kO3/R1tZmyJAhyY7t3LmTxo0bkzdvXgwMDChRogQTJ04kMjIy2Xl169b94FNwgF69en2wxGv16tWUKVMGY2NjTExMKF68OJMnT056PCoqirFjx+Lo6Ii+vj6WlpZUrFiR7du3J53zsSVtKY21V69eGBsb8/r1a5o3b46xsTF2dnaMGTOG2NjYf30NU8Lf35/Bgwfj5OSEsbExefLkoX79+ly+fDnZee7u7mhoaLBo0SLmzp2Lo6Mjenp6nD9/HoCDBw9SunRp9PT0KFiwICtWrPjoc1YUhVWrVlG2bFkMDAywsLCgQ4cOuLq6Jp1Tt25djh49ioeHR7Kld2n1b++5fy4zU6vVzJ07l2LFimFgYIC5uTmlS5dmxYoVQOL3cNy4cQA4OjomxfXXEjIHBwdatmzJvn37KFeuHPr6+kkzLv+2fC4mJobRo0djY2ODgYEBderU4f79+8nOScl71d3dPSmhmTVrVlJsf/X5b0va1q9fT5kyZZLet+3atcPFxeWDfjLq/SeEEF8qmeER4gsRGhrKvXv3Ppjd+ZTWrVtz7NgxLl++jL29/UfPuXPnDiEhIQwaNChVbb969YrmzZszcuRIjIyMeP78OQsXLuTWrVucO3cuVW0B7Nixg8GDBzNs2DCWLFmCpqYmr1+/5tmzZ0nnjB49mj/++IO5c+dSrlw5IiMjefLkCYGBgekWa3x8PK1bt6Zv376MGTOGS5cuMWfOHMzMzJg+fXqqn9dfgoKCAJgxYwY2NjZERESwf/9+6taty9mzZz8YaP/0008ULVqUJUuWYGpqSpEiRThx4gTffPMNtWvXZufOnSQkJLBkyRJ8fX0/6O/7779n48aNDB8+nIULFxIUFMTs2bOpXr06Dx8+xNramlWrVjFgwADevHnD/v370/zc/i4l77lFixYxc+ZMpk6dSu3atYmPj+f58+dJ9+v069ePoKAgVq5cyb59+5KWhzk5OSW1ce/ePVxcXJg6dSqOjo4YGRn9Z1yTJ0+mfPnyrFu3jtDQUGbOnEndunW5f/8+BQsWTPHzy5s3LydOnKBp06b07duXfv36AfznrM78+fOZPHkyXbp0Yf78+QQGBjJz5kyqVavG7du3KVKkSNK5GfX+E0KIL5YihPgidOvWTdHW1lbu3LmT7HidOnUUZ2fnf73u+PHjCqAsXLjwX8/ZsWOHAihr1qz54LH4+PhkX/9GrVYr8fHxysWLFxVAefjwYbIY69Sp88E1PXv2VOzt7ZP+PXToUMXc3Pxf+1AURSlZsqTStm3b/zxnxowZyn/9+PuvWHv27KkAyq5du5Jd07x5c6VYsWL/2e8/AcqQIUP+9fGEhAQlPj5eadCggdKuXbuk425ubgqgFCpUSImLi0t2TaVKlRQ7OzslNjY26Vh4eLhiZWWV7Dlfv35dAZSlS5cmu97T01MxMDBQxo8fn3SsRYsWyb4Pn5KW95y9vb3Ss2fPpH+3bNlSKVu27H/2s3jxYgVQ3NzcPnjM3t5e0dLSUl68ePHRx/7e1/nz5xVAKV++vKJWq5OOu7u7Kzo6Okq/fv2SPbeUvFf9/f0VQJkxY8YH527YsCFZ3MHBwYqBgYHSvHnzZOe9fftW0dPTU7p27Zqsn/R6/wkhxNdClrQJ8QWYNm0aW7duZdmyZVSoUCFV1yqKkuZ+Q0JC0NHRSfZ1586dpMddXV3p2rUrNjY2aGlpoaOjQ506dQA+WKqTEpUrVyYkJIQuXbpw8OBBAgICPnrO8ePHmThxIhcuXCA6OjpFbacmVg0NDVq1apXsWOnSpf9zWWBKrVmzhvLly6Ovr4+2tjY6OjqcPXv2o69X69at0dHRSfp3ZGQkd+7coW3btujq6iYdNzY2/iDeI0eOoKGhQffu3UlISEj6srGxoUyZMh+tLpZeUvKeq1y5Mg8fPmTw4MGcPHmSsLCwVPdTunRpihYtmuLzu3btmmy5nr29PdWrV09aKphRrl+/TnR09AfL7Ozs7Khfvz5nz55Ndjwj339CCPElkoRHiBxu1qxZzJ07l3nz5jF06NBUX//XIMnW1vZfzylQoECyc/9iYmLC7du3uX37NjNmzEj2WEREBLVq1eLmzZvMnTuXCxcucPv2bfbt2weQ4kTk73r06MH69evx8PCgffv25MmThypVqnD69Omkc3766ScmTJjAgQMHqFevHpaWlrRt25ZXr179a7upjdXQ0BB9ff1kx/T09IiJiUn1c/q7H3/8kUGDBlGlShX27t3LjRs3uH37Nk2bNv3o6/XPKl/BwcEoioK1tfUH5/7zmK+vb9K5/0xab9y48dFkMr2k5D03adIklixZwo0bN2jWrBlWVlY0aNAgWUL9KamtgmZjY/PRY59aDvm5/mr/Y/Ha2tp+0H9Gvf+EEOJLJffwCJGDzZo1i5kzZzJz5sxkN+6nxqFDh9DQ0KB27dr/ek6FChWwsLDg8OHD/PDDD0nHtbS0qFixIgBPnjxJds25c+fw8vLiwoULSTMlwEf3TNHX1yc0NPSD4x8bdPfu3ZvevXsTGRnJpUuXmDFjBi1btuTly5fY29tjZGTErFmzmDVrFr6+vkmzPa1ateL58+cffX6piTUjbdmyhbp167J69epkx8PDwz96/j+LB1hYWKChofHR+3V8fHyS/TtXrlxoaGhw+fLlj1Z2y8hqbyl5z2lrazN69GhGjx5NSEgIZ86cYfLkyTRp0gRPT08MDQ0/2U9qiyv88zX665iVlVXSv1PzXk2pv9r39vb+4DEvLy9y5cqV5raFEELIDI8QOdacOXOSbur+5+xKSm3YsIHjx4/TpUuXpFmcj9HV1WXcuHE8efKEhQsXpqjtvwab/xw4f6x0tYODAy9fvkxWZSowMJBr1679a/tGRkY0a9aMKVOmEBcXx9OnTz84x9raml69etGlSxdevHhBVFTUZ8eakTQ0ND6I4dGjRx/s3/NvjIyMqFixIgcOHCAuLi7peEREBEeOHEl2bsuWLVEUhffv31OxYsUPvkqVKpV0rp6eXppm5D4mpe+5vzM3N6dDhw4MGTKEoKCgpOpmf71W6RXb9u3bky238/Dw4Nq1a8mKRaT0vZqa2KpVq4aBgQFbtmxJdvzdu3ecO3eOBg0apOXpCCGE+JPM8AiRAy1dupTp06fTtGlTWrRowY0bN5I9/s/9T6Kjo5POiY6OxtXVlQMHDnDkyBHq1KnDmjVrPtnnhAkTeP78ORMnTuTSpUt07twZBwcHYmNjcXV1Zd26dWhpaSV98l69enUsLCwYOHAgM2bMQEdHh61bt/Lw4cMP2u7Rowe//vor3bt3p3///gQGBrJo0aIPNofs378/BgYG1KhRg7x58+Lj48P8+fMxMzOjUqVKAFSpUoWWLVtSunRpLCwscHFx4Y8//qBatWr/OiuQmlgzUsuWLZkzZw4zZsygTp06vHjxgtmzZ+Po6EhCQkKK2pg9ezYtWrSgSZMmjBgxApVKxeLFizE2Nk6qAgdQo0YNBgwYQO/evblz5w61a9fGyMgIb29vrly5QqlSpZKq8pUqVYp9+/axevVqKlSogKamZtLM3r/53Pdcq1atKFmyJBUrViR37tx4eHiwfPly7O3tkyqW/ZWUrVixgp49e6Kjo0OxYsUwMTFJ0Wv1T35+frRr147+/fsTGhrKjBkz0NfXZ9KkSUnnpPS9amJigr29PQcPHqRBgwZYWlqSK1euD8qsQ2JCN23aNCZPnsx3331Hly5dCAwMZNasWejr66f5Aw0hhBB/ysqKCUKItKlTp44C/OvXf51rZGSkFCxYUOnQoYOye/duRaVSparvQ4cOKa1atVKsra0VbW1txcTERClbtqwyZswY5fnz58nOvXbtmlKtWjXF0NBQyZ07t9KvXz/l3r17CqBs2LAh2bmbNm1SSpQooejr6ytOTk7Kzp07P6h8tWnTJqVevXqKtbW1oqurq9ja2iqdOnVSHj16lHTOxIkTlYoVKyoWFhaKnp6eUrBgQWXUqFFKQEBA0jkfq9KW0lh79uypGBkZffC6fKry28fwjyptsbGxytixY5V8+fIp+vr6Svny5ZUDBw588Dr8VaVt8eLFH213//79SqlSpRRdXV2lQIECyoIFC5Thw4crFhYWH5y7fv16pUqVKoqRkZFiYGCgFCpUSPnuu++SVfsLCgpSOnTooJibmysaGhqffJ5pec/9s3La0qVLlerVqyu5cuVKeh59+/ZV3N3dk103adIkxdbWVtHU1FQA5fz580nttWjR4qPx/VuVtj/++EMZPny4kjt3bkVPT0+pVavWB1UPFSVl71VFUZQzZ84o5cqVU/T09BQgqc9/Vmn7y7p165TSpUsrurq6ipmZmdKmTRvl6dOnyc5Jz/efEEJ8LTQU5TNKNAkhhMj24uPjKVu2LPny5ePUqVNZHY4QQgiRqWRJmxBCfGH69u1Lo0aNkpb9rVmzBhcXF1asWJHVoQkhhBCZThIeIYT4woSHhzN27Fj8/f3R0dGhfPnyHDt2jIYNG2Z1aEIIIUSmkyVtQgghhBBCiC9Wji1LPX/+fDQ0NBg5cmRWhyKEEEIIIUS2s2rVKhwdHdHX16dChQpcvnz5X8/19vama9euFCtWDE1NzY+OsX/77Tdq1aqFhYUFFhYWNGzYkFu3bn1w3vv37+nevTtWVlYYGhpStmxZ7t69m55PLVVyZMJz+/Zt1q5dS+nSpbM6FCGEEEIIIbKdnTt3MnLkSKZMmcL9+/epVasWzZo14+3btx89PzY2lty5czNlyhTKlCnz0XMuXLhAly5dOH/+PNevX6dAgQI0btyY9+/fJ50THBxMjRo10NHR4fjx4zx79oylS5dibm6eEU8zRXLckraIiAjKly/PqlWrmDt3LmXLlmX58uVZHZYQQgghhPgKKOqPb2Kd0TQ0P76X3L+pUqUK5cuXZ/Xq1UnHSpQoQdu2bZk/f/5/Xlu3bt0UjbFVKhUWFhb8/PPPfPfddwBMnDiRq1ev/udsUmbLcUULhgwZQosWLWjYsCFz5879z3NjY2OT7YatVqsJCgrCysoqaWd1IYQQQgiRfSiKQnh4OLa2tmhqZr/FSNFvSxMXn/nzBRp57n0wftXT00NPT++Dc+Pi4rh79y4TJ05Mdrxx48Zcu3Yt3WKKiooiPj4eS0vLpGOHDh2iSZMmdOzYkYsXL5IvXz4GDx5M//79063f1MpRCc+OHTu4d+8et2/fTtH58+fPZ9asWRkclRBCCCGESG+enp7kz58/q8NIJiYmhkJV3PHxU2V638bG+YmIiEh2bMaMGcycOfODcwMCAlCpVFhbWyc7bm1tjY+PT7rFNHHiRPLly5esCqirqyurV69m9OjRTJ48mVu3bjF8+HD09PSSZoEyW45JeDw9PRkxYgSnTp1CX18/RddMmjSJ0aNHJ/07NDSUAgUK4OnpiampaUaFKoQQQggh0igsLAw7OztMTEyyOpQPxMXF4eOn4q3HS0xNMy++sLBwCtgX/WAM+7HZnb/754yQoijptspp0aJFbN++nQsXLiQbm6vVaipWrMgPP/wAQLly5Xj69CmrV6+WhOdT7t69i5+fHxUqVEg6plKpuHTpEj///DOxsbFoaWklu+bfpvlMTU0l4RFCCCGEyMay8+0HZubWmTqW/Ov+nZSOYXPlyoWWltYHszl+fn4fzPqkxZIlS/jhhx84c+bMB0XE8ubNi5OTU7JjJUqUYO/evZ/db1plv4WR/6JBgwY8fvyYBw8eJH1VrFiRbt268eDBgw+SHSGEEEIIIb5Gurq6VKhQgdOnTyc7fvr0aapXr/5ZbS9evJg5c+Zw4sQJKlas+MHjNWrU4MWLF8mOvXz5Ent7+8/q93PkmBkeExMTSpYsmeyYkZERVlZWHxwXQgghhBDiazZ69Gh69OhBxYoVqVatGmvXruXt27cMHDgQSLz14/3792zevDnpmgcPHgCJVZH9/f158OABurq6STM2ixYtYtq0aWzbtg0HB4ekGSRjY2OMjY0BGDVqFNWrV+eHH36gU6dO3Lp1i7Vr17J27dpMfPbJ5ZiERwghhBBCCJEynTt3JjAwkNmzZ+Pt7U3JkiU5duxY0kyLt7f3B3vylCtXLunvd+/eZdu2bdjb2+Pu7g4kbmQaFxdHhw4dkl339+IJlSpVYv/+/UyaNInZs2fj6OjI8uXL6datW8Y92U/IcfvwfI6wsDDMzMwIDQ2Ve3iEEEIIIbKh7Dxey6rYsvNrkhPkmHt4hBBCCCGEECK1JOERQgghhBBCfLEk4RFCCCGEEEJ8sSThEUIIIYQQQnyxJOERQgghhBBCfLEk4RFCCCGEEEJ8sSThEUIIIYQQQnyxJOERQgghhBBCfLEk4RFCCCGEEEJ8sSThEUIIIYQQQnyxJOERQgghhBBCfLEk4RFCCCGEEEJ8sSThEUIIIYQQQnyxJOERQgghhBBCfLEk4RFCCCGEEEJ8sSThEUIIIYQQQnyxJOERQgghhBBCfLEk4RFCCCGEEEJ8sSThEUIIIYQQQnyxJOERQgghhBBCfLG0szoAIYQQQgghchK1Ogq1OvOG0Wp1VKb19SWShEcIIYQQQohU8PQug0lE5i2UCg9XZ1pfXyJZ0iaEEEIIIYT4YskMjxBCCCGEEKlgl/chpqammdZfWFgYkDfT+vvSSMIjhBBCCCFEKmhqGqKpaZiJ/SVkWl9fIlnSJoQQQgghhPhiScIjhBBCCCGE+GJJwiOEEEIIIYT4YknCI4QQQgghhPhiScIjhBBCCCGE+GJJwiOEEEIIIYT4YknCI4QQQgghhPhiyT48QgghcixFUYiLiUeVoEZLW/PPLy00NDSyOjQhhBDZhCQ8QgghsgVFUQjyDcXbzZ8g31CC/cMI9gsl2C+cEP8wgv3DiAqPJjY6LvErJp7YqLiPtqWplZj86OhqY2xuhIm5IaaWxpiYG2FqaYSJpTF58luS1z43Ng65yG1rgZa2ViY/YyGEEJlBEh4hhBCZKi42Hg8XL1yfevLe1Q8vVz+83PzwcvMnJjI2XfpQq9SoVWriYxOICo/BzzPwP8/X0tYkj50VNgVyYV/clsJlClC4tD12RWzQ0pLV30IIkZNJwiOEECLDhAaG8+rhW9yfvcfd5T1uz97h7vIeVYL6o+dramlibWdJrrwWmOcxxSK3Kea5//rTBGMzQ/QMdNEz1EVPXxc9A110DXTQ0tJErVJQqVSoEtSoElSoVWpio+OJCI0kLCiS8OD/f4UGhuPrGYi3uz++bwOJj0vA280fbzd/7l90SYpHz0CHgiXtKOhsR5Gy9pSuXpS8jrllyZwQQuQgkvAIIYRIFyqVmrcvvHC57cqz229wue3K+ze+Hz3XxMKIQqXssCtig61jHmwL5iFfQWusC1iho5u5v5rUajWBPqH4uPvj5eaH69N3vH70ljePPYmJjMXltisut12TzreyMadU9aKUql6E0jWKkr+wjSRAQgiRjWkoiqJkdRCZJSwsDDMzM0JDQzE1Nc3qcIQQIkdTFAXPVz7cPfeUexee8fTma6LCYz44L1/BPDiWzI9jifw4OuejcOkC5M5nme2TBJVKjZerL68fvsX16Tue3X7Di7tuJMSrkp1naW1GtWZlqdGyHKVrFEVbRz5LFOJzZOfxWlbFlp1fk5xAEh4hhBApFhEaxf2LLtw995S755/i/z442eMGRnoUK+9I8UoFcapUiBIVC2JiYZRF0aa/2Og4nt9x5dG1lzy+9pLnd92Ii4lPetzY3JCqTctQo0U5KtRzRldfJwujFSJnys7jNUl4ciZJeIQQQvyn8OBIrh27z6WDd3lwySXZ/Tc6etqUqlaECvWcKVOrOI5O+b6qamdxsfE8uvqSq4fvce34A0IDwpMeMzDSo+43lWnRuw6FSxfIwiiFyFmy83hNEp6cSRIeIYQQHwgPieT6sQdcOniH+xeTJzkFiualQj0nKtR3pmS1Iugb6mVhpNmHSqXm6Y1XXD16n6tH7hPg9f/Zr+IVHGneqw6121SQ10uIT8jO4zVJeHImSXiEEEIAEB+XwJ2zTziz8zo3Tz5Kdq+Ko3N+arepQK3WFclf2DoLo8wZ1Go1j6+94timS1w9ci/ptTQ2M6TRt9Vo2acu+QrJ6yjEx2Tn8ZokPDmTJDxCCPEVU6vVPL3xmnN7bnL50F0iQqKSHnNwykftNhWp1boCdkVssjDKnC3EP4yT265ybNMlfN8m7gekoaFBjVbl6DSsKUXLOWRtgEJkM9l5vCYJT84kCY8QQnyF/L2COb7pEqd3XEtWeMDS2oy631SmUZdqODrlz8IIvzxqtZq7555y+PcL3Dr9OOl42drF6TSiKeVql8j2leuEyAzZebwmCU/OJLUzhRDiK6FWq7l/0YWjGy5y48RD1OrEz7sMTfSp2boC9dtXoVSNomhpaWZxpF8mTU1NKjUsRaWGpXB79o7dK09yYd9tHlx6zoNLzylSxp4uY5pTrVlZSXyEECIdyQyPEEJ84cKDIzm1/RpHN1zEy80v6XjpGkVp0asO1ZqVlfLJWcTXM5B9q09z4o/LxEYnlrcuXaMoA+d1pmBJuyyOToiskZ3HazLDkzNJwiOEEF+oAO9g9q06w7HNl4iJjAUSZ3MafludFr1qY1/MNosjFH8JDQxn3+oz7F9zhriYeDQ1NWjSvSY9J7fFPJdJVocnRKbKzuM1SXhyJkl4hBDiC+P5yoc9P5/i7K7rSdXBHJ3z07pvPep+UwkDY/0sjlD8G1/PQH6fuZdLB+8AiQlqt7Etad2/Pjq6sgpdfB2y83hNEp6cSRIeIYT4AiiKwqMrL9i76nSyG+JLVStC55HNqFDfWe4LyUGeXH/Fmik7ef3oLQD5Clkzavl3lKxWJIsjEyLjZefxmiQ8OZMkPEIIkYMpisK9C8/YuvgIz269STpepXFpOo1oinOVwlkYnfgcarWa09uvsXHeAYL9wtDQ0KBVv3r0ntJWZunEFy07j9f+ii0o2DvTEx5Li7zZ8jXJCSThEUKIHEhRFO6cfcLWxUd4ftcNAF19HRp3rUG77xvIppZfkMiwKH6bvocTW64AYF3AipHLv6Nc7RJZHJkQGSM7j9f+iu3oo4IYmWhlWr+R4SpalHbNlq9JTiALgoUQIgdRFIVbpx6zdckRXt53B0DPQIfmPevQYWhjrGzMszQ+kf6MTA0Zufw7aretyPJRf+D7NpBJ3yyj2Xe16DezPUamhlkdohBCZGsywyOEEDnEi3vu/DZ9N09uvAJAz1CXlr3r0mFIYyzyyM+0r0FUeAwb5u7j8O8XAMhla8H41X0oXaNY1gYmRDrKzuM1WdKWM0nCI4QQ2Zzfu0A2zNnP+b23gMQZndb96tN+cCPMc8vPsq/Ro6svWDZyM95u/mhqatBzSls6DmuCpqZsGityvuw8XpOiBTmTLGkTQohsKiwogp3Lj3Po9/PExyYA0LBzNXpOaUtuW4ssjk5kpdI1irH6wnRWjtvK2V032DBnP09vvGbc6j6YmBtldXhCCJGtSMIjhBDZTFxsPAd/Pcv2ZceICo8BoFT1ogyY3ZEiZe2zODqRXegb6TH2l96Uql6UXyZs49bpxwxvOI+pGwZRqJRdVocnhBDZhiQ8QgiRjdw+85g1k3fy3tUPgEKl7Og9tZ3soyM+SkNDg6bda1KolB1ze6/B2z2AUc0WMGxJNxp9Wz2rwxNCiGxBEh4hhMgGvFz9+HXqLm6eegSARR5T+s5oT/2OVeS+DPFJRcrY8/PZqSwa9Du3zzxh6dCNvHnsSf/ZHdHSkvePEOLrJgmPEEJkoeiIGLYvO8b+1WeIj0tAW0eLtt83oMuYFhiZGGR1eCIHMbEwYta2oWxbcpQtiw5z4NezBHgFM25VH/QMdLM6PCGEyDKS8AghRBa5feYxP43Zgv/7YAAq1Hdm4LzO2BWxyeLIRE6lqalJ9/GtyF/YmqVDN3Ll8D2C/EKZ+ccQTC2Nszo8IYTIEpLwCCFEJgvyDeW36buTykxbF7Bi4LzOVG1aRu7TEemi7jeVsbQ2Y/Z3q3l28w2jmy9k3u6RWNtZZXVoQgiR6WRhrxBCZBK1Ws2R9RfoX2065/feQlNTg28GNeLXyzOp1qysJDsiXZWuUYwlR8eTO58F7177Mqb5QjxeeGV1WEIIkekk4RFCiEzw5rEno5st5Ofx24gMi6Zw6QIsPzmJAXM6om+kl9XhiS+UQ3Fbfjw+kQLF8hLgHcLYlot5ftc1q8MSQohMJQmPEEJkIFWCiq1LjjC80Tye33XD0FifQfO/ZcXpyRQt55DV4YmvQG5bC5YcHkfxCo6EB0cyuf1ySXqEEF8VSXiEECKDvHvty+jmC/ljwSFUCWpqtCzHb9dn06Z/fSkVLDKVqaUx8/eOonSNokRFxDCl4wpe3nfP6rCEECJTyG9cIYRIZ2q1mkO/n2dIvdm8uOeOkakB41f3ZeqGgVjlNc/q8LI9RVGIj0sgOjKWsOBIgvzC8H0fzHt3f3w8gwgOCCcqIgZVgiqrQ81RDIz1mbV1KCWrFiEyLJrJHZfz+tHbrA5LCCEyXI6p0rZ69WpWr16Nu7s7AM7OzkyfPp1mzZplbWBCCPE3/u+DWDZiE/cuuABQrk4JRv/Uk9z5LLM4sqynVqsJ9g/H2zMIH89A/N4HExoUSVhwJCGBEYQERhAaGEFoUCRqtZKiNrV1tNA30MXQRB+rPKZYWZthmccEy9ymWFqbksvGDLuCebCyNpWiECQmPbO3D2Nq5xU8u/WGSe2XsejgGByd8md1aEIIkWE0FEVJ2W+VLHb48GG0tLQoXLgwAJs2bWLx4sXcv38fZ2fnFLURFhaGmZkZoaGhmJqaZmS4Qoiv0LndN/l5/FaiwmPQM9Ch74z2tOxTF03Nr2syXaVS897NH1cXL948e8/b1354vw3E910QcbEJqW5PU1MDHV1ttLS1UKvVxEbHk9pfXUYm+hQobP3nVx7si9hQtIwdJmaGqY7nSxAZHs2UDst5ftcNizymLD06HlvHPFkdlhBA9h6vZVVs2fk1yQlyTMLzMZaWlixevJi+ffum6Hx5swghMkJkeDS/jN/Gud03AShesSBjVvb6KjYQVRQFL48Antxy4+VjT94888L9hTexMfEfPV9TS5M8tubY2Flinc8S81zGmJobYm5ljJmVMRa5TDC1MELfUBcdXW20dbQ+uN/pryVvsdHxxETHERsTT3hwJIF+YQT6hhHkF0aQfxhBfuH4eQXj5RGIWqX+IBYNDQ3si1pTsqIjzpUKUrKiI7lszDLkdcqOIkKjGNd6CW5P35HXIRdLjozHysY8q8MSIluP1yThyZlyZMKjUqnYvXs3PXv25P79+zg5OX30vNjYWGJjY5P+HRYWhp2dnbxZhBDpxuWOKwu/X4ePRwCamhp0HduSLqObo6WtldWhZQhFUfB848fjW648vuXKk9uuBPqGfXCenoEOBYvbUrCELQ7FbLC1z4WNnSV5bC3Q1snc1yYuNgEvjwDevvLF45UPb1/74fbci/fuAR+ca2NnSYVaxajRtBSlKxf8Yr+PfwnyDWVMy0V4u/nj6JyfJUfGYWRikNVhia9cdh7cS8KTM+WohOfx48dUq1aNmJgYjI2N2bZtG82bN//X82fOnMmsWbM+OC5vFiHE51Kp1OxacZw/Fh5GrVKTx86KCWv64lylcFaHlu5iouN4cO01N88+5eZ5F4L9w5M9rq2jRfGyBShRzoFCzrYUKmFLXvtc2b4SXXBAOE/vuPHkjhtPbrnh9twr2b1DphaGVG3gTI2mpShbrQi6ejnmttdU8Xb3Z3TzhQT7hVGxgTOztg794hM9kb1l58G9JDw5U45KeOLi4nj79i0hISHs3buXdevWcfHiRZnhEUJkqgDvYBYOWMfj668AqNOuEsOXdsPI9Mu5HyQ4IJxb51y4cfYp96++SrZETVdPmxLl7ClVuSClKheiWNkC6OnrZGG06SMyPIand9y4fvoJ104/JSw4MukxQ2N9qjd2pvm3VSlezv6LK4Dw8r4741ovJjY6npa96zBkUdcv7jmKnCM7D+4l4cmZclTC808NGzakUKFC/Prrryk6X94sQojP9eDSc+YP+I3QgHAMjPQYsqgrDTpV/SIGh5Hh0Vw7/ZTzB+/x4NrrZIUB8tiaU7WhM1UbOOFcseAXO9vxF1WCiie33bh68jFXTz0hyO//y/YKlshL8y7VqNe6HIbG+lkYZfq6duw+c3quQVEU+s/uSPvBjbI6JPGVys7jNUl4cqYcnfA0aNAAOzs7Nm7cmKLz5c0ihEgrtVrN9h+PsXXRYdRqhUKl7Jjy+/fYFszZla2iImK4cfYZl4895M6lFyTE/39vmyIl81O1oRNVGzjjWDzvF5HUpYVarebZPQ9O7rrJpaMPkyrN6RvqUq91OZp3qUZh53xZHGX62LvqNL9N342GhgZzdw2nQr2UVUEVIj1l5/GaJDw5U45JeCZPnkyzZs2ws7MjPDycHTt2sGDBAk6cOEGjRin7FEreLEKItAgJCGfRoN+5d/4ZAE261WTwgm/RM9DN4sjSRlEUHt14w4ldN7l68gnxcf8vFV2gsDV1WpahfpsK2NjJ3kH/FB4Sxem9tzm24ybv3fyTjlesU5xuwxpRvGyBLIzu8ymKwvKRf3By6xVMLIxYeXYKNgVyZXVY4iuTncdrkvDkTDkm4enbty9nz57F29sbMzMzSpcuzYQJE1Kc7IC8WYQQqffkxisW9P+NAO8Q9Ax0GLq4G42+rZ7VYaVJSGAEZ/bd4cTOm8kqlOVzzE3tFmWo07wM9kW//FLa6UFRFB7fdOXYjhtcPv4oqex1hVpF6TasESXKO2RtgJ8hLiaesa0W8/K+O4VK2fHjsQk5NrkXOVN2Hq9JwpMz5ZiEJz3Im0UIkVKKorBv9Rl+n7UXtUqNXREbpqz/HocSOWvpkqIoPL7lytGt17l2+knSkjUDIz3qtS5Hk06VKVIy/1e7XC09eHkEsGP1Oc7uv5uU+JSrUYRuwxvhXMExi6NLG//3QQxtMI/QgHAadq7GmJ97yXtEZJrsPF6ThCdnyt41Q4UQIgvExcSzdNhGfpu+G7VKTb32lfnp9OQcleyoVGqunHjEyPYrmdBtDZeOPSQhXkWxMnaM/KEjW69NY9ic9hQtZScD2c9ka5+L0Qs6se70eJp0rIyWtib3r75ibOdVzB2yCT+v4KwOMdVy57Nk8m/90dTU4MzO6xzffDmrQxJCpMGqVatwdHREX1+fChUqcPnyv/9f9vb2pmvXrhQrVgxNTU1Gjhz50fP27t2Lk5MTenp6ODk5sX///mSPJyQkMHXqVBwdHTEwMKBgwYLMnj0btfrDDaAziyQ8QgjxN4E+IYxvu5QzO66jqaXJwHmdGb+mLwY5pBpXXGw8x3bc4Psmi5k39A9ePvJEV0+b5l2q8vOhkSzfO5wmnSpjYKSX1aF+cfIWsGLk/I6sOz2Bpp0qo6mlydWTTxjQeDHbV51NKnaQU5SpVZzeU9sBsHryDlyfeGZxREKI1Ni5cycjR45kypQp3L9/n1q1atGsWTPevn370fNjY2PJnTs3U6ZMoUyZMh895/r163Tu3JkePXrw8OFDevToQadOnbh582bSOQsXLmTNmjX8/PPPuLi4sGjRIhYvXszKlSsz5HmmhCxpE0KIP72458bs71YT6BOCsbkhk38fQPk6H9/nK7sJC47k4KYrHN12ndCgxP1jjM0MaNW9Oq2/q4m5lXEWR/j1cXvhzaqZB3hy2xWAfA65GDyzHeVrFs3iyFJOrVYzs9sv3Dr9mPyFrfn53FT0DSVZFhkrO4/X/ootINgn05e05bKwSdVrUqVKFcqXL8/q1auTjpUoUYK2bdsyf/78/7y2bt26lC1bluXLlyc73rlzZ8LCwjh+/HjSsaZNm2JhYcH27dsBaNmyJdbW1vz+++9J57Rv3x5DQ0P++OOPFMWe3r7sjRSEECKFTu+4xk9jthAfm0CBonmZuWVIjig5HRIYwf71lzi85RrRkYkbLefOa067PrVpKjM5WcqxWF4WbRvI+UP3WbfgCO/dA5jS6zdqNy/D91NbY5knew3kPkZTU5Oxv/RmUO3ZvHvty6Z5B/h+XuesDkuILLfbrRUGxpk3jI6OSJwhDgsLS3ZcT08PPb0Pf87HxcVx9+5dJk6cmOx448aNuXbtWprjuH79OqNGjUp2rEmTJskSo5o1a7JmzRpevnxJ0aJFefjwIVeuXPkgecpMkvAIIb5qKpWaddN3s//XswBUbVqGcav7YGRikMWR/bfggHD2rrvIka3XiI2OBxI3xOw8sAE1mpRES1sriyMUABoaGtRvU54q9Uvwx4pTHN58lUvHHvLg+itGLehM1QbZfwbR1NKYkct7MO3blez/9SxVm5WlTM1iWR2WEF8lOzu7ZP+eMWMGM2fO/OC8gIAAVCoV1tbWyY5bW1vj4+OT5v59fHw+2eaECRMIDQ2lePHiaGlpoVKpmDdvHl26dElzv59LEh4hxFcrJjKWBd+v48aJhwB0G9uSbuNboqmZfW9vDA2KZOfqsxzbfoPYmMREp0jJ/HQd2pAqDZykAEE2ZWRiwMCpbWj0TUWWTdzNm2fvmfX9Blr1qEG/iS3Q1dPJ6hD/U6WGpWj2XS2Ob77M0mEbWX1perb/UECIjNTR8XCmL2kbhA2enp7J+v3Y7M7f/fN3gqIon/174lNt7ty5ky1btrBt2zacnZ158OABI0eOxNbWlp49e35W32klCY8Q4qsU5BvKjG4/8+qBBzp62oz7pQ+121bM6rD+VVxsAof+uMKOX84SGR4DQLEydnQd1ohKdYpLopNDFHLKx4+7h7Jp6XH2rb/E4T+u8vjWGyYu7459EetPN5CF+s/qyP2LLvh4BPDbtN2MXP5dVockRJbR0TRARzPzkn4dzcQPuExNTVOUaOXKlQstLa0PZnP8/Pw+mKFJDRsbm0+2OW7cOCZOnMi3334LQKlSpfDw8GD+/PlZlvBk348xhRAig7g/92Jk0wW8euCBqaURC/aNzrbJjqIoXD7+iO+bLub3BUeJDI+hYAlb5q7vx7I9w6hct4QkOzmMrp42/Se3Ys7vfTG3Msb9hQ/D2y7n2PbrZOc6QoYm+oxZmbgfz4ktV7h56lFWhySE+Be6urpUqFCB06dPJzt++vRpqldP++bZ1apV+6DNU6dOJWszKirqg5USWlpaWVqWWmZ4hBBflQeXnjOn12oiw6KxdczD3J3Ds21xgid33Niw6CjP7nkAYJnHlF5jmlK/bQW0tOTzqpyuYp3irDo6mqXjdnD38ktWTtvHw+tvGLWwE/oGulkd3keVql6UdgMbsm/1aZaP3Mzaa7MwMTfK6rCEEB8xevRoevToQcWKFalWrRpr167l7du3DBw4EIBJkybx/v17Nm/enHTNgwcPAIiIiMDf358HDx6gq6uLk1Pi/YYjRoygdu3aLFy4kDZt2nDw4EHOnDnDlStXktpo1aoV8+bNo0CBAjg7O3P//n1+/PFH+vTpk3lP/h+kLLUQ4qtxavs1VozajCpBjVOVQszYPBgzK5OsDusDfl7B/PbDEa6cSPwEXU9fhw7969K+Xx2puvYFUqvV7F9/mY1Lj5MQr6JoaTtm/NoLy9zZ8/dUXEw8Q+rNwfOVD8161GLEsh5ZHZL4wmTn8VpWxZbWfletWsWiRYvw9vamZMmSLFu2jNq1awPQq1cv3N3duXDhQtL5H1sxYG9vj7u7e9K/9+zZw9SpU3F1daVQoULMmzePb775Junx8PBwpk2bxv79+/Hz88PW1pYuXbowffp0dHWz5sMcSXiEEF88RVHYueIEG+cm7gZdp10lxqzsha5+9rpRPC42gX2/X2TH6rPERsejqalBk06V6TasEVbWZlkd3meLiY4jMCCcoIAIgvzDCQmOJDYmnrjYBOJi44n988+42AS0tbXQ0dNGV1cbPT3tpL+bmBlilcsEq9wmWOUxwcTU4ItZ0vfktitzBm8iLDiKPLbmzPytD47F8mZ1WB/15PorxrZaDMCPxybgVLlQFkckviTZebyW0xIekUgSHiHEF02tVvPbtP+Xne40oim9prTNdpXY7lx8zpo5B3nvHgBAyUqODJ7RFsfitlkcWeqEh0Xz1s0fTzd/3roF8NbNH+93wQQFhBP15z5B6UlHVxur3CZY5zXHsYg1BYtY41jEmgKOubPtsrD/4uUewPT+63nv5o+BkR6TfupOpTrFszqsj/pxxCZObb2Kg1M+fj47BW0dWSUv0kd2Hq9JwpMzScIjhPhiJcQnsHTYJs7vuQnA93M70W5gwyyOKjnf98H8Ovcg108/BcAitwn9JrakXuty2X7mIjI8hudP3vHskScujzxxfeVLcGDEf16jp6+D5Z8zNBaWRugb6KKrp/3nl07ibI6uNiqVmrjYBOLjEoiLTSD2z5mf0JAogvzDCfQPJyw06l/70dTUwNbOikLFbChdwYFyVQpim98y27+mAOEhUcwbupmHN96gqanBwGltaNWjRlaH9YHQwHD6V5tOWFAkfWe0p+OwJlkdkvhCZOfxmiQ8OZMkPEKIL1JMZCzz+v7K7TNP0NLWZMzK3tTvWCWrw0qiVqs5uvU66xcfIyYqDk0tTdr2rEnXYY0wMtHP6vA+Kjgwgrs33vD0gQfPHnri4er/0apiuaxNKeCQmwIFc1PAMRf57KywymOKZS5jDI300i3piIuNJyggggC/MLw8g3B77YvrK1/cXvoQGvJhMmSd15xylQtSrkpBylZyxNzSOF3iyAjxcQmsnL6P03tuA9CmV00GTG6V7WYmT227yo/DN6FnqMvaq7OwtrPK6pDEFyA7j9ck4cmZJOERQnxxwoMjmdZlJc/vuKJnoMPUDQOp1LBUVoeV5L27Pysm7+HxLVcgcfna0FnfYF/UJosjSy4uLoFnD95y7+Yb7t54w+vn3h+ckzefBSVK2+FU2o4iTrYUcMyNYRYXVlAUhaCACNxe+fL8yTse3HbF5dE7EhJUyc5zLluAOo1LUquBE5a5sl/xCkVR2P3reTYsOQ5Ag3YVGLWgU7aq0KcoCuNbL+Hx9VdUbVqGmVuGZHVI4guQncdrkvDkTJLwCCG+KAHewUzusJy3L7wxNjdk9vZhOFXKHjdUJ8Sr2LvuIltXniY+LgF9Q116j21Oy+7Vss0n98GBEVw978K1C895cs+D2Nj4ZI8XKWFLmYoOOJcpQInSdlhYZd9Zkr+Ljorlyf233L/lyv1brri+/P/GeZqaGpSu4ECdxiWpWd8JU3PDLIz0QxcO32fx2B2oVWoadajEyB86ZJv3C4DHCy8G15mNKkHNgn2jKVs7e95zJHKO7Dxek4QnZ5KERwjxxfD1DGRiu6V4uweQK685c3ePxCGb3PT/8rEnyyftxu3PWZLyNYsybE57bOwsszgyCPQP5+r5Z1w+84wn9z1Qq///a8HSyphyVQpSrkohKlQtlC1nQtLC3zeUy2eecvHUU54/eZd0XEtLk6p1ivFN12o4ly2Qbe75uXz8EQtGbkWtUtPs2yoMm9M+28QGsGridg6tO0+RMvasOD0pWyVkIufJzuM1SXhyJkl4hBBfBC9XPya0W4r/+2DyOuRi/r7R2BTIldVhoUpQsXPNObauPINapcbUwpDvp7SmXpvyWTpgjYqM5cLJx5w99oinD94muxenqJMtNRs4UaVmUewL5clWA+uM4PM+mIunn3Dp1FNev/j/sr2izvlo360aNes7oa2jlYURJjp/6D5Lxm5HrVZo1aMGg6a3yTbfmxD/MHpXnEJ0ZCwT1/aj7jeVszokkYNl5/GaJDw5kyQ8Qogcz+OFF5O+WUaQbyj5C1uzYP9ocuW1yOqw8H0XxKIx23l21x2A2i3KMGh6W8yzaBmYoii8fObFsX13uHDyCTHRcUmPFS+Zn1oNnajZwAkb26x/7bKK+xs/Dmy/wZmjD4mPSwAgt7UZbb6tTLN2FTA2McjS+M7sv8OP43ehKArtetei/+RW2Sbp2brkCH8sOISNfS7WXpuFrl722udK5BzZebwmCU/OJAmPECJHe/PYk8kdlhEaGIGDUz7m7xmFRZ6s//99/tB9fp6+j6iIGAyM9Bg6+xvqtymfJbFEhsdw7vgjjh+4y5sX/793Jb+9FU3blqdOo5LkyWueJbFlVyHBkRzdc5tDu24REhQJgJGxPt/2qUWbzlXQy8JNa0/uusXyybsB6DCgLn3GNc8WSU9MZCy9K00h2C+MgfM60/b7BlkdksihsvN4TRKenEkSHiFEjvXinjtTOi4nIjSKImXsmbd7BKZZXGo4MjyaX2bs5/yh+wA4lbdn3NKuWXKvjq93CAd33OT4/rtJm37q6GpTq4ETzb+pQMly9tlioJydxcXGc/7kE/ZuuYbHGz8gsex2r0ENaNCidJbdq3J023V+nr4PgJ6jm/Lt4OyRXBzbdImfxmzB1NKIDXfmYWSavQpAiJwhO4/XJOHJmSThEULkSM9uv2FqxxVERcRQolJB5uwYjrFZ1g6unt1zZ+HIrfh5haCppUnXoQ35dlB9tLQz7/4PRVF4ct+D/dtvcP3C86QCBAUcc9P8mwo0aFEG0yx+nXIilUrNueOP2LTqHP6+oQAUKmbDgJFNKFu5YJbEtH/DZdbOOwTA5JU9qNWsdJbE8XeqBBXf15zJu9e+dB/fiu7jW2V1SCIHys7jNUl4ciZJeIQQOY7LHVemdFhOVEQMpaoXZdbWoRhm4WadarWafb9fYsOS46hVavIWsGLckm8pUd4h02JQJag4f/IJ+7deT3bjfdnKBfmmazUq1ywisznpIDYmngM7brBj/eWkWbMqtYoydEKLLFkW+OvcQxzYeBk9fR2W7BxCYed8mR7DP106cIcf+q3F2MyQjfd+yPIPIkTOk53Ha5Lw5EyS8AghcpQX99yY1H4ZUeExlKlZjFnbhqJvmHUbXYYFR7J0/E5unXcBoE7Lsgyf2x5D48xJwFQJKs6deMy2dRfx8gwCQFdPmwbNy9D22yo4FLbOlDi+NqHBkWz97SJH9txGpVJjaKTHwDFNady6XKYmlqoEFTP6r+fu5ZfkzmvO8n3DsMydtb/f1Go1A2vN4u0Lb3pMaE23cS2zNB6R82Tn8ZokPDmTJDxCiBzj5X13JrVfRmRYNKWqFWHOjuHoG2VdsuNy34P5w7fg7x2Cjq42A6e3oVnnKpky4FWp1Fw4+Zitv13k/dtAAMzMDfmmWzWaf1Mx222e+aV66+bPj7MP4vLIE4DKNYsycmprrHJn3n5FEWHRjGy/kvdu/pQoZ8+CLQPR1dPOtP4/RmZ5xOfIzuM1SXhyJtkZTAiRI7x66MHkDsuJDIvGuWphZm8flmXJjqIo7F13kXFdVuHvHYKtfS6W7RlK82+rZniyo1arOX/iMQM6/sKiaft4/zYQUzND+gxryKbDI/m2T21JdjJRAcfcLF3Xh77DG6Gjo8WtKy8Z0OkXzp94TGZ9nmhsasDMtb0xNjXA5b4HK6ftybS+/03N1uUpUCwvEaFRHFx7LktjEUIImeERQmR7bx57MqHdUiJConCqXIi5O0dk2T070ZGx/DhhF1dOPAKgdvMyDJ/XAaNMiOfxPXfWLD3B6+eJ9+iYmBnQoXt1WneugmEWznSJRO6vfVk8Y3/S96dmAydGTG6VaQnovSsvmdb3d9QqNf0mtqR9vzqZ0u+/kVkekVbZebwmMzw5kyQ8Qohszd3lPePbLCEsKJLiFQsyb/cIjLJo80cvjwDmDN6E+wsftHW0+H5Ka1p0q5bhszoern6sX3mGG5deAGBopEfH72rQ5tsqGGXSvUKpkZCgws8vDF+fUHx8QgkMjCAiIobIyFgiI2IT/4yMJTo6Dg0NDTQ1NdDQ1EBLUwNNTU20tDQxMtbDwtwIM3NDzC0MsTA3xMzcEBsbc2xtzdHOxMp3qZEQr2LHhktsW3cJlUqNTT4LZi7tgmORzLmX6uCmK6yZcxANDQ3mbepPuepFMqXfj/n7vTy9prTl21HNsywWkbNk5/GaJDw5kyQ8Qohs6/0bX8a2WkywXxhFyzkwf+/ILNvX4+6lFywYtZWI0Ggschkz5ZfvcK7gmKF9BvqHsXnNeU4duo9araCppUmztuX5bmA9zLN4vyGA6Og4XF39eP3Kl9evfXnnGYSPbygB/uFJ5bAzgra2JvnzW2Jvnwt7h1w4OOSiYKE85M9vmW0q0b1y8WLuhF34vA9G30CX8bO/oUb9Ehner6IoLJ+0m1N7bmOZx5RVR0ZjZmmU4f3+mzO7rrNk8AZy5TVn470f0NbJ2nuLRM6QncdrkvDkTJLwCCGyJf/3QYxpsQi/d0E4Oudn0cExmJhn/sBNURR2r73ApqXHUasVipUpwNRfviOXjVmG9RkXl8CezVfZsf4ysbHxANSoV4LeQxti55Arw/r9L2q1gqurHw/ue/DyhTev/kxw/i2x0dXVxsbGDGsbM3LnNsHYWB8jI71kX4aGuigKqBUFtVqNWqWgViuoVGrCwqMJDYkiJCSKkOBIQkKjCA6KwssrmJiY+I/2aWVlTNmyBShTzp5yZe3Ja2uepQlQWEgU8ybu4sFtNwB6fF+Xrv3qZPhmpTHRcQxvuwLPN35Ua+jMtNU9s+x1iIuNp2e5SQT7hTFxbT/qflM5S+IQOUt2Hq9JwpMzScIjhMh2QvzDGNtqMe9e+5KvkDVLDo/DIk/m/5+NiYpj2cRdXDr2EICmnSozaEa7DK2A9fCOGyvnH8HTPQAA5zIF6DuiEc5lCmRYnx+jKArvPIO4f9+De/fcefDAg/CwmA/Os7Q0onARawoXtsHRMRc2ec2xsTHD3NwITc30H2Sr1Qr+fmG4ewTg4RGAh1sA7u7+vHnjR3y8Ktm5efKYUq68PXXqlqBCBYcsWQanSlCxdtlJDuy4CUCN+iUYN6sdBhlcSv3Ns/eMbL+ShHgVw+Z8Q/Mu1TK0v/+yZdFhtiw6TPGKBVl+YmKWxSFyjuw8XpOEJ2eShEcIka1EhEYxoe1S3jz2JHc+C5YeHU+e/FaZHkegbygz+m/gzbP3aOtoMXBaG5p3ybgqbKHBkfy2/BSnjzwAwMLKmAGjmlCvaalM+3RepVLz+LEnFy8859rVVwQEhCd73MBAl9Jl7HB2zkfhIjYUKWKNZTZYWgcQGxvPs2dePLjvwYMHHjx38SIhQZ30uLm5IXXqFqdBQ2ecnPJl+ozHyYP3WDn/CPHxKhwLWzPzxy7Y5LPI0D73r7/E2h8Oo6evw08HRlAgi/ZkCvYL47uyE4mPS2DFqUkUK5+xS0FFzpedx2t/xeYf7JvpCU9uC+ts+ZrkBJLwCCGyjZjIWCZ3XM6zW28wz23CksPjyZ8FgzRXFy9m9F9PgE8oZpZGTF3Vk5IVM2aQplarOX34Ab+tOEV4aDQaGhq0aF+R3kMbYJwJxRkSElQ8fPiWSxdfcOXyC0JCopIe09HRwrlkfsqXt6dsOXuKFcubbYsF/FN0dBzPnr3n+tVXnL/gQkjw/59X3rzm1G/gRPMWZbCxMc+0mJ498mT22B0EB0ZgaWXM/FXfZejGsGq1mml9fufelZcULJGXZXuGZ9n+PEuGbODMzuvUa1+ZCb/2y5IYRM6Rncdrf8U26XpT9I11Mq3fmIh45lc7kS1fk5xAEh4hRLYQH5fAzO6/cPfcU4zNDFl0aCwFnfNnehx3Lj7nh+FbiI6Mxa5QHmav64uNnWWG9PXeM5Dlcw7x6K47AI5FrBkxpRUlStllSH9/URSFJ0/ecerkYy5fekF4+P+XqpmY6lOjRlFq1y5G2XL26Oll3i/0jKJSqbl7142zZ55y5fLLpHuANDU1qF27OB07V6Z4cdtMicXfN5Rpw7fi9toXY1MDFqz6jiIlMq7vIL8wBrX4kbDgSDoMqEvf8S0yrK//8uqhB8MazENLW5PN9xdgldc8S+IQOUN2Hq9JwpMzScIjhMhyarWahd//zsX9t9E30mP+3lGUqFgw0+M4svUaq2cfRK1SU6ZqIab88h0mGbB3iEql5uCOG2z85RyxsfHo6evw3cB6tP22Kto6GTeD4usTyqlTjzl18jFeXiFJx83NDalRsyi16xSnbNkCOWYWJy1iYuK5du0Vx4895N6fiSZA6dJ2dOxUharVCmfIvUd/Fx4WzbThW3B5/C5Tkp4bZ54ya+BGNDU1WLFvOIVLZv4HCQBjWi7i6Y3X9JjQmm7jWmZJDCJnyM7jNVnSljNJwiOEyFKKovDr1F0c+PUs2jpazNo2lAr1nDM1BpVKzfqFR9m3/hIAjdpXZNic9ujopv/yn7du/vw46wAuj98BULZyQUZNbZ1h93MkJKi4dPE5x44+5P59j6Tj+vo61K1bgkZNSlKqlB1aWhlbOSw7evPal927b3Hu7DNUqsT7ffLbWdKtW3UaNiqZoYlPZEQMU4ZtweWRZ6YkPfNHbOHS0YcUcsrHin3D0MqCpPb8npssHPg7ufKas+n+/CyJQeQM2Xm8JkULciZJeIQQWWr3ypP8PmsvABN+7Ue99plbtjYuNp5Fo7dx9eQTAHqObkrnQfXT/ab2hHgVu/+4yta1F4iPV2FopMeAUU1o2rZ8htxAHx4ezdEjD9m/706y4gPlytnTpGkpatYqhoGBbrr3mxP5+4exf99djhy+T2RkLADFi+dlyLBGODnly7B+MzPpCQ4IZ0CTxUSERtNnfHM6DqiXIf38l7jYeHqUmUhoQDjTNw+ievNymR6DyBmy83hNEp6cSRIeIUSW+WtTQoD+szvSfnCjTO0/MjyaWd9v5PEtV7R1tBizqDN1W6X/IOydRwALpuzllYsXAJVrFGHY5FbkyYC9fLzeB7Nv722OH3+UdK+KhYURrduUo0mT0lhn4P5BOV1UVCwHD9xj65ZrREfHAdCoUUn6DahLrlwmGdJnZiY9p/bcZtnEXejp6/DribFY58+Ye9P+y/rZ+9j10wnK13Pih90jM71/kTNk5/GaJDw5kyQ8Qogscff8U6Z3WYkqQU37wY3oP7tjpvYfHBDO1N7rcHXxwsBIj5m/9qZ01ULp3s/pIw/4ecFRYqLjMDY1YNDYZjRoXjrdZ3XevPblj81XuXLlBX/9VC9YMA/tO1aifn0ndDNged6XKjAwgvXrLnLixCMgcflf127V6dipcoa8jn9PekzNDPlxfd8M2WBWURQmdFvD41uuVK5Xgplre2d6eW5vd3/6VJqKoiisvzUX24J5MrV/kTNk5/GaJDw5kyQ8QohM9+qhB+NaLyEmMpZ67SszbnWfDN99/u+83wYypddveL8NxNzKmDnr+1HYOX2XLkVGxPDLwqOcPZY4aC5dwYEJc9uTK503UH392pctf1zl8qUXSceqVClEh46VKVfePtMHtF+S58+9+HnlaVyeJc7M5ctnwcTJrTJkmVtkRAwTB2/m5dP3WOc1Z8Wm/lhYpf8eR29f+zKk1TIS4lVMX92Tao1KpnsfnzK18wrunH1K+yGN6T+rQ6b3L7K/7Dxek4QnZ5KERwiRqfzeBTKi8XyC/cIoW7s4c3YMz5DiAP/G7bkXU3qvI9g/HBs7S+Zt6I9tOn+a/uyRJwun7sXnfTCaWpr0GFCXzr1rpWthgBcvvNmy+SrXrr0CQEMD6tYrQfceNXHIgNmBr5WiKJw985S1a88TGBCBpqYG3/WsSddu1dO90ENIcCSjeq/DyzMI5zIFWLCmZ4bMKG1YfIxdv57H1j4Xa46PydT/fwDXjz1g1nersMhjypbHi77Kghniv2Xn8ZokPDmTJDxCiEwTGRbF6OaL8HjuhYNTPpYeGYeRafqXff43T++6MbP/BiLConEoZsO8Df2xTMcZF5VKzY71l9jy20XUKjXWtuZMmNse5zIF0q2PN699WbfuArduugKJiU69ek50614dB8fc6dZPasXExuPrH0ZQcCSBwZEEBkcQGJT4Z3hELAkJKuITVCQkqElIUJGgUqNWKxjo62BkqIeRoe7//zTSwzqXKfnyWpDf1hxLc6Msn6mKiIhhxbKTnDv3DICSJfMzcXIr8qbzfjKe7gGM6PkbkRExNGlTjlHT2qT7c4+KiKFvg4WEBEYwcHob2nxXM13b/5T4uAS6Oo8jPDiSH/aOpHwdp0ztX2R/2Xm8JglPziQJjxAiUyTEJzDt25Xcv+iClY05y09OJHe+zLtp+v7Vl8z6fiOxMfE4lbdn5m990nWPnbCQKBZM3cvd668BqN+sNEMntMDIRD9d2g8KimDD+kscP/YQRUncNLNBQ2e6dauOXQGrdOkjJWLjEvB8H4SrRwDungG4vQ3E7a0/3r6hZNRvEwN9HfLlNSd/XgsKOeahdIl8lCiaF/0s2BT1zOkn/LTiFJGRsRga6jJ8ZBMaNnRO16TkzrXXTBuxBbVaYdDYZrTtUjXd2v7L0W3X+Xn6PkwtDFl/biJGJgbp3sd/+WnMFo5tukSjLtUZs7JXpvYtsr/sPF6ThCdnkoRHCJHhFEXhp9FbOP7HZfSN9FhyeByFS6ffrMen3LrgwtzBm4mPS6BineJM+bkH+ulYkvmVixdzxu/E1ysEPT0dhk1uSaOWZdOl7djYePbuuc22rdeTKofVrVuCPv1qky8TEsbIqFiePPfi4VNPHj59h8srbxIS1B8918hQFysLY6wsjLC0MMLKwggrC2NMTQ3Q0dZCR0cLbW1NtLW00NHWRENTg6joOKKi4oiIiiUyMpbI6DgiImLw9g3lnXcIfgFhqNUf/prS1takWCFrSpXITymnfJRxyo9pJg3afXxCmD/vME+eJO6lVL++E6PHNkvXMt97t1xj7bKTaGpqMHdlDyqkc0ENVYKKQS1+xPONH52+r0fvcc3Ttf1PeXL9FWNbLcbQWJ/tLkvQkxLp4m+y83hNEp6cSRIeIUSG+2uvHU1NDaZvHkzVpmUyre/rp5/ww/AtJMSrqNbImYnLu6Orl373LJw+/ICf5h8mLjaBvPktmb6kMwWL2Hx2u4qicP68C+vWXsDXNxSAYsXzMnhwQ0qWyv/Z7f+bhAQVD5+94/rtNzx8+o5Xbn4fJBzGRnoUtM+Fg10uHO1z4WiXC8cCVliYG6V7PHHxCfj4hvHeJxjP98G4vPLm0bN3+AdGJDtPS1OD8qXtqVezGLWqFMHMNGOTH5VKzfZt19m08TJqtUKhQnmYM68D1tbpU/ZbURSWzjrA6cMPMDbR56fNA8iXzjN5N848ZdbAjejqabPu9ARy25qna/v/Ra1W07PcJPzfBzNl/ffUal0h0/oW2V92Hq9JwpMzScIjhMhQV47cY17vX1EUhYHzOtP2+waZ1vflYw9ZOHobqgQ1tZuXYdzSLmjrpM/u7nFxCaz98QSHd98GEvfWGT+3PSbpMNB++zaQ5ctO8PDBWwBy5zahX/+61G/gjKZm+t/LEhEZy+0H7ly79Zprd1wJj4hJ9ng+G3NKO+WnjHN+SjvnJ5+NeZbeU6MoCj5+YTx2ecfDZ+949PQ9Hu8Ckx7X0tKkYhl76tUoRq2qRTAxTp9lhR/z9Mk7ZkzfR3BwJBYWRsyd14Hi6bSPTlxcAuO/34jLI0/sHHLx0+YBGBrppUvbkPg6ju+6hie3XWnQtjxjl3RJt7ZT4q89eaq3KMf0TYMytW+RvWXn8ZokPDmTJDxCiAzz5rEno1ssJDYqjtb96jFo/reZNlC+cPg+i8fuQK1SU79NeUYv7ISWdvokOwF+YcwZt5PnT96hoaFB9wF16NqvzmeX1o6JiWfrlmvs2nmDhAQ1enradOlajY6dqqCvn773q4SFR3P+ygvOX3vBw6fvUKn+v0zNzNSAGpUKUamsA6Wd85PbKmM23UxP77yDuXD1BeevvOCVm1/ScR1tLRrVKUHH1hUp5JAxRR18fUOZOnkPrq5+6OvrMH1mO6pUSZ8laEEB4Qz7bi0BvmE0bl2OMTPapku7f3nxyJOR3/yEhoYGa46PoUBh63Rt/7+4Pn3H4Dqz0dHVZueLHzFMp/vdRM6XncdrkvDkTJLwCCEyRLBfGMMbzcP/fTDl6zkxZ/uwdEs4PuXcgbssHb8TtVqhUfuKjPihY7qVvn3l4sWMUdsI9A/H2NSACXO+oXLNop/d7vXrr/j5p9P4+CQuX6tStRDDhjdO1ypgCQkqbtx14+T5p1y7/Yb4BFXSYwXyW1K9YiGqVy5EqeL5cnSpYM/3QZy7+oJzV57j5hGQdLxiGXs6talI5XKO6T5TFhUVy6wZ+7lzxw1NTQ3GjGtO06al06Xtx/c9GNd/A4qiMHVRZ2o1SN+qZrMHbeT66afUbV2OCT92Tde2/4uiKPStPA0vNz9Z1iaSyc7jNUl4ciZJeIQQ6S4uNp6J3/zIs5tvyFfImhWnJmGcjhXR/su5g/dYMnYHiqLQtFNlhs1tn26bml4958LCaXuJjYmnQMHczF7Wlbz5P69wgK9vKD+vPM21q4n76eSxNmXo0EZUr1Ek3WbDXrv5cfTMY85cciE0LDrpeCGH3DSu40StakXIn9ciXfrKbp48f8/uQ3e5eP1l0r1IBfJb0ql1RZrWd0ZXJ/3u54qPV7F08TFOn34CQJ++dejarVq6fB/X/3yGnRsuY2JmwK87B2OVO/1+h71++p5hbZajoaHB2pNjyV8wT7q1/Sm/zdjD3l9OUa9DFSas6Ztp/YrsLTuP1yThyZkk4RFCpCtFUVg2cjOntl7FyNSA5ScnYZcON/GnxKWjD1k4aitqtULzLlUZMqtduiQ7iqKwa9MV1q88A0DF6oWZ/EPHzyo5rSgKJ0885pefTxMVFYeWliYdO1Wme48a6VLtS61WuH7nDbsO3eX+47dJxy3NDWlYx4mm9Zwp7Jh5A9us5u0byt6j9zhy6hFRf1a7s7UxY1CvutSumn7JpaIorPvtAju23wCg87dV6T+g7me3Hx+fwMhe63j93JvyVQox7+fu6ZbIA8z6fgM3zj6jQbsKjF38bbq1+ylPb75mTItFGJsZsuP5ErTTMQEVOVd2Hq9JwpMzScIjhEhXB9aeZc3knWhqajB7x3Aq1nfOlH6vnX7CvKF/oFapadKxMsPnpc/MTnx8Aj/9cIRTh+4D0LpzZQaObvpZy/OCgiJZtvQ4164lzuo4O+dj9NjmODjk+ux4o2PiOHn+KbsP3cXTKxhIrGBWu1pRmjUoScWyDmjn4OVqnysyKpajZx6zfd8tAoMjAShX0o5h/eqnawK4d89tVv2SmCB371Gd3n3qfHabb938GdrtV2Jj49N9f56Xjz0Z0e4nNLU0+e3kOGzT4b2YEiqVmm4lxxHiH8683SOoUC9zfl6I7C07j9ck4cmZvt7fekKIdHf/kgtrp+0GoO/MDpmW7Ny64ML84VtQq9Q0aFs+3ZaxhYVEMXnIH5w6dB9NTQ0Gj2/OkPEtPivZuXzpBf36/Ma1a6/Q0dGi/4B6LFvR/bOTnZCwKH774zId+v7Kj2vO4OkVjLGRHl3aVWLH2gHMGt+aqhUKftXJDoCRoR6dWldk6+p+fNepGrq62tx/4knfUZtY/MtJQkKj0qWf9h0qMWRoQwC2/HGNzZuufHabBRxz039kYwDW/XQa9zd+n7gi5YqWsqNineKoVWp2rjmXbu1+ipaWJtWblwPgyqF7mdavEOLrIjM8Qoh04fM2gGEN5hEeHEnDztUY83OvTKnI9uD6a6b3/Z34uARqtyjD+KVd0qU4go9XMFOG/sE7j0AMjfSYvKAjlaoXSXN7YWHR/LzyNGfPPAWgYME8TJzcikKFPm9WISgkkp0HbnPg+AOiY+KBxDLSHVpXoFn9khjKho7/yccvlNUbL3L+6gsgcY+hwb3q0qJRqXR5/+7adZNfVycmEMOGN6Jtu4qf1Z6iKEwbsZXbV19R1MmW5Rv7p1uBCZd77ozu9Ata2ppsvDCZXDbps6fQp9y/5MKkb5ZhZmXMtmdLcnTBDJE+svN4TWZ4ciZZLCuE+GxxMfHM6/0r4cGRFClrz/Cl3TMl2Xl2z51Z328gPi6Bao2cGbckfZKdNy99mDr0D4ICI8htbcbcn7rh8Bnleh89fMu8uYcICAhHU1ODzt9W5bueNdHVTfuP4ICgCHbsv8XBEw+JjUsAoFgha3p0rEqNyoUzfdAYExdPUGgUEVGxhEXG/PlnLBFRscTExqOlpYm2lmbSn9pamujqaGNpZkgeC2NyWxhjbKiX6fv72OQxY9b41nzz9B0/rTvLK1c/Fv1ykhv3XBk/pAmmJp+3r1KnTlWIiY5n08bL/LzyNBaWxtSpUzzN7WloaDBqWhv6d/iZl8+8OLzrVrotbStR3oGSlRx5ctuNI1uv0WtMs3Rp91NKVSuCkakBoYERvLzvTomKBTOlXyHE10MSHiHEZ1s1cTuvHnpgamnE1A0D0U3nPWM+5vWTd0zr8zsxUXGUr1mUicu7p8umog9uuzFrzHaiImNxKJSHeT/3IFeetH2aplYrbN92jY0bLqNWK+S3s2TixJaUcMqX5viCQyLZvOsGh089JC4+say0U9G89OxcnaoVHDM0YVCrFd76BOPhFcRb32De+Ybg6ROCp28wfkERn92+vq42uS0Tk59C+XNRwtGaEo7W2NtaopWON+h/TBnn/Kxd0oNdh+7w25bLXLr+CpeXPkwb04Kyznaf1XaP72oQFBTB4UP3mT/vEGZmBpQta5/m9qxym9BnWENWzj/CxlVnqVG/BLmt02c2pk3Pmjy57cbxHTfoMqQhepnwf1lbR5sK9Zy5dPAON089koRHCJHuZEmbEOKzHP/jMitG/YGGhgbzdo+gfN303SPkY965+TO28y+EBkVSspIjc9b3Qz8dlm5dPPWExdP3ER+volR5e2b+2AXjNH7CHxwcyfwfDnH3jjsAjRqXZMTIJmmuwBYXn8Dew/fYvPs6kVGJVcZKFrel17fVqVTWIUMSndCIaJ6+8eHJa2+evPHm6RsfIqJi//V8XR0tTAz1MTHSw8RQDxMjfUwM9dDX0yZBpaBSq0lIUCf+qVITG5dAYEgE/sERhEX+e7v6utoUdchDCUdryhbLR9VSDhjqZ9xSvRevfZi55DDvvUPQ1NTgu45V+a5z9c+6/0mlUjNr5n6uXnmJkZEey1Z0/6zljGq1mjH91vPsoSe1GzkzZUGnNLeVLM4EFX3qL8DPK4SR8zvSpGPldGn3U87sus6SwRsoWDI/qy5Mz5Q+RfaVncdrsqQtZ5KERwiRZq8eeDC6xULiYxPoNaUt345qnuF9+nuHMLbzL/h5hVDYOR8Ltgz8rPLQfzm44warl5xAURRq1C/BxLnt0dVL26fbDx548MPcQwQGRqCnp83wkU3SvAmloihcufmaVRsu8N4nBEhcujawZx3Kly6QrolOfIKK+8/fceWBKzcfe+DuFfTBOXq62hTMZ0V+a3PsbMyxs7bAztocOxsLzIz10xxPTGw8/iER+AdF4BMYzqu3/ri4+vDCw4+oP+9N+ouujhYVnQpQp0IhapUrhJW5UZr6/C9RUXEs/+0MJ84l3nNVqkQ+po1ugU2etM+kxMbGM2H8Th4/8iSPtSmr1/TG3Dzt+1O9eeHN0O6/olYrLFzdk7KV02dmZM9vF/h94VEci+fll8OjMmWZYUhAOF1KjEVRFP54tJDctl/mvlAiZbLzeE0SnpxJEh4hRJqEBoYzrME8/N4FUbVpGaZvHpSu+4J8TFhwJOO6rObta1/yOeRiyc4hmFsZf1abiqKwcdVZdqy/DECrjpUYNK55mu6BUasVtm65yuZNV1CrFeztczF9Zrs0V2B74+7Hyt/Pc+9R4j46lhZGfN+jNk3qOaOpmT6D0MDQSK4/dE9KcqJi4pI9bmdjTslCeSlV2JaShfNSyC5XplZ6+2sZnYubD8/e+HDtoRvv/EKTHtfQAOdCealXsQgtajlhYZq+G9yevviMpatPExUdh4mxPvMmtaVsybQvcQsPj2bI4E28fxdMmbIFWLT4W7Q/476znxce5fCuWxQomJvV2waly7LO8NAoetScS2x0PAu3DKR01UKf3WZKjGq2AJfbrgxb0o0WvT6/jLfIubLzeE0SnpxJEh4hRKqp1WqmfbuSu+eeYuuYh5/OTMbYLH0Hmv8UEx3H5O/W4nLfAytrU5buGop1vs/7FFitVrNmyQkO7rwJQM/B9enSp3aaPtGOiIjhh3mHuHnjDQBNm5Zm6PBGaVrCFhEZy9o/LnHo5EPUagVdHS06t6lEt/ZVMDT8/KVcoeHRnLn5khPXXXj00ivZY1ZmRtQo60iNso6ULZYf88+8aT+9KYqC2/tALt59w6V7r3nm6pv0mK6OFo2qFKNjo7KUKJh+m916+YQwc8lhnr/yQVtbk6mjWlC/ZtoLD7i7BzB08Caio+Po2KkyAwc1SHNb4WHR9G33E6EhUQwc05R2Xaulua2/Wzl9L8e23aBGk5JM/aVnurT5Kdt/PMqmHw5SpUlpZm0dmil9iuwpO4/XJOHJmSThEUKk2o5lx9g47wC6+josPzmJgs75M7Q/VYKKOYM3c/PcM4zNDFiyfTD2RT9vQKtWq/nphyMc338XgGGTWtKyQ6U0teXuHsD0aXt4/y4YXV1tRo5qQpM0LGFTFIUL116y4rezBP25KWbd6kUZ2KsOttbmaYrtLzGx8Vy+78qJqy5cf+yOSqVOeqyYQx5qlStIzbIFKeZgnW6zR5nBLyicy/dcOXzpCS5u/09+nAvZ0KlROepXLoKuzufX54mNjWfe8mNcuPYSDQ0YOaAh7f7cPyYtrlx+wYzp+wCYv7ATlSunfRbl6N7b/PTDEczMDdl4aCSGRnppbusv7i99GNR8KVrammy5Ou2zZ1JT4tUDD4Y1nIehiT67Xy1Ll4qLImfKzuM1SXhyJkl4hBCp8vjaSya0XYparTBqxXc06VYzQ/tTFIWfpu7lxM6b6OppM2/TAEpWdPysNlUJKpbOPsjZow/R1NRg9PS2NGpVNk1tXbnykgU/HCY6Oo48eUyZNfsbihbLm+p2vHxDWPbrGW7edQMgv60FYwY1okLptFfzAnj11p9dp+5z5uaLZPfCFLXPTZNqJWhUrRjWliaf1Ud28eS1N7vPPODMjRck/JnQWZoZ0qdNVdrVK/VZS8cgsfDA8rVnOHjiIQC9vq1O72+rp/kel5U/neLA/ruYWxjy27q+WFqmLalIiFfRv+PPeHkG0eP7enQfUDdN7fzT8HYrePX4HQOmtKZd71rp0uZ/UanUdC46mojQKFacmkyx8g4Z3qfInrLzeO2v2PyC/DI94cljmSdbviY5gZSlFkKkWIh/GPP7/4ZardCgU1Uad62R4X1u+/kMJ3beRFNTg/HLun52spMQr2LB1L1cPvMUTS1NJsxtT93GJVPdjlqtsGnjZbb8cRWAMmULMH1Gu1TfhJ6QoGLnwTts3HGN2LgEdLS16NahCt3aV0Evjfv0qNRqrtx3ZcfJe9xzeZd0PG8uU5pUL06T6iUomM8qTW1nZyUL56Vk4bwM71Kbg+cfs+/cQ/yDI1my+Rx7zjxgWJfa1CiT9tLdWlqajB7YCAtzIzbuuMbGHdcICY1iRP8Gabrn6/uB9Xn48C1urv4smH+YBQu/TdPsmraOFj0H1Wf+5D3s3XKNVh0rYWbx+YUcGneoxKvH7zi15xZte9XM8OIFWlqalKxWhBsnHvLoynNJeES2Nu7hcHSNM29j57iIuE+fJP6VbGcshEgRtVrNokG/E+QbSoGieRm2uFuGD4BO77vDlhWnABg0oy01Gpf6rPbi4hKYM2Enl888RVtbi2kLO6Up2YmIiGHqlN1Jyc437SuyaPG3qU523N4G8P3YLfy6+RKxcQmUK2nHhhW96NOlRpqSnYioWLYfv0uHsRsYv/wQ91zeoaWpQYPKRVkzpRP7f+zLoI41v8hk5++szIzo07YqB37sx7ie9TE3McDdK4gxSw8wbOFeXnr4p7ltDQ0N+nSpwYgBDdDQgAPHHzDnx6MkJKhS3ZaurjbTprdFT0+bu3fc2b3rZprjqt3ImULFbIiKjGXnxitpbufv6rQsi46uNu4vfHj15N2nL0gHZWoWA+Dh1ReZ0p8Q4usgS9qEECny1w3FegY6rDg1GYcSad88MyXuX3vFtD7rUCWo6fR9PXqP+7yS17Ex8cwau4O711+jq6fN9CXfUql6kVS34+sbyuSJu3B3D0BXV5vRY5rSKJWJmFqtsPfoPX7ddJG4eBVmJgYM6VOXJvWc05REhkfGsP3EPXacvEdkdOKngKZGerStV5r2Dcpgk+vr/nkXHhnDxkO32HnqPvEJKjQ0oEUtZwZ3qomVWdpnQs5ecmHeimMkJKipX7M400a3SNNMz9GjD/hxyXG0tDT5aWUPipewTVM8t6++YurwLejoarPhwPB02Yx04aitXDj8gBZdqzF09jef3d6nuD7xZHDdOegb6bHn9TK00+H+K5HzZOfxmixpy5nkJ4kQ4pMeX3vJHwsOATBkUbcMT3Y8Xvkyd/BmVAlq6rQsS88xTT+rvbi4BGaPS0x29PR1mL2sa5r2LHn1yocpk3YTGBiBlZUxc+Z1oFgq79fx9Q9j4coT3HnoAUCVCo5MGNqUXGm4fyMsMoadJ++x4+T9pA1BHfNZ0blxOZrVKIF+GvcRSi1FUQiLiiUsKoa4+ARi41XEJSQQF68iLkGFoigYG+j9+aWLiYEehnq6mVYcwcRIn2FdatO+QRl+2XWZMzdfcuTSU67cd2Vqv8bUKp+2ggENapfA0FCPKfP3c+7Kc4yMdBk7qHGqk9bmzctw97YbFy8+Z97cg/z2ez/09VP/vatYvTAly9nz5L4H29ZdZMSU1qlu458ad6jEhcMPuHD4Pv0nt0IvDXGlhoNTPkwtjQgLiuTlAw+cKmVOSWwhUktPSw89rc8vEJKa/kTaScIjhPhPoYHhLPx+HWq1QsPO1WjcpXqG9hcSGMHMAeuJioihZCVHRi/s/Fn7+yTEq5g3cRd3riUmO/NWdqdUGu4NuHnjNbNnHSAmJh4Hh1z8sKAT1qn4BF1RFE5fdGH52jNERMaip6vN4N51adusbKoHyKHh0Ww/cY+dp+4n7ZtTMJ8V/dtXo26FIhmSSCSo1Lh6B/LC04/3gWH4BofjGxyOT1A4PsHhxMQlpKo9DQ0wNdTHLrc5jjaWONhY4GBtiaONJflym6Gjlf4VumzzmDFvaEu+beLFgg1neO0ZwNhlB+nYqCxDv62Fvm7qB/PVKhZk+piWzFx8mMMnH2FrbU639lVS1YaGhgajxzbj2bP3eHmFsOWPq/TrXzfVsWhoaNB7SAPG9FvPqUMP6Na/LrnyfN4nwWWqFSaPrTl+XiHcvuBCzTRuoJtSmpqalKxahGvHHvDs5htJeIQQ6SLHJDzz589n3759PH/+HAMDA6pXr87ChQspVqxYVocmxBdLURR+HLaJAO8Q8hWyZsjCLhnaX1xsAnMGb8LHMwgbO0um/tITXb20/5hSJSQWKLhx8QW6etrMXtY1TcnO4UP3+GnFKdRqhfIVHJgxsx3Gxvopvj4yKpbFv5zi3JXnAJQokpepo5pjl88yVXHExiWw/cRdNh2+lVRxrbBdLvq0rUq9iumX6KjUal6+88flrR/P3/rx3NOPV+/9iY3/7/tUDPV00NXRRk9HC11tbXS1tdD9cyPMiOg4IqJjCY+OJUGlRlEgNDKG0Egfnrj7JGtHW0sTZ3trqpSwp0rxApR0tEnXBKhUEVs2zOrK6t1X2Xb8LrtPP+CeiydzBregkF3qN4mtW70Yw/pFsmLtWX7dfAmbPGY0qJW6fXqMjfUZNrwx06ftZdfOmzRs6IyDY+5Ux1KynD2lytvz+J4He7dc4/vRnzc7qqmpSe0WZdjz20UuHnmY4QkPQImKBbl27AHP77lmeF9CiK9Djkl4Ll68yJAhQ6hUqRIJCQlMmTKFxo0b8+zZM4yMPr8ajRDiQwd+PcvNU4/Q0dNm8roBGKRikJ9aiqLw05TdPLvrjpGJPrN+64OZZdr/b6vVapbOPphUoGD6km9TvYxNrVZY99sFdu64AUCTpqUYNboZOqnYzf6Nux/TFh7inVcwWlqa9OpcjW4dqqKdins9FEXh3K1XrNxxCe+AMCCxrHTftlWpXb5wuiQ6vsHhXH/mwXUXD249f0toZMwH5xjr61LMLg/21hbYWJhgbWGMjaUp1n/+XS8F91soikJsvIqI6FiCI6Lx8A3C3ScYN58g3HyCcPcNIiYugYeu3jx09Wbt0RsY6ulQoWh+qhQvQO1SBcmf2/yzn6+ujjYjutahSkl7Zq09wZt3gfSasZXhXWrToWHqZ93atyiPl3cIuw/fZf6KY+S2Mqa0U+r2p6pRsyjVaxTh2tVXLFt2gmXLu6fpe9u5Vy0e3/Pg+P67dO1XBxPTz9s8tk7Lcuz57SK3zj8jMjwGI5OM+zkAUKxCYiXG53fcMrQfIcTXI8cWLfD39ydPnjxcvHiR2rVrp+ia7HwTnBDZzasHHoxqtoCEeBWDF3ahdd96GdrfztXn2Lj0OJpamsz5vS/laxZNc1uKorBi3mGO77+LppYm0xZ2onq9EqlqIyFBxaIFRzh79hkAvXrXonuPGqkaCB8/+4Sla04TF5eAdW5TZo1rhVOx1N2Q/tzdl2VbLvDgxXsAclsYM7RzLRpXK/5ZiY5arfDQ1YtzD15z/Zk7rt5ByR431tfF2cGG4gXyUNwuDyUKWJM/l1mG33ejVit4BYZy+4UnN5+/5dYLT0IiopOdU6mYHe1qlKRe2cIpSrI+JSg0ijm/neTaw8QBdt2KhZk1sFmq74FSqdRMX3iQyzdfY2qiz+pF3bGztUhVG35+YfTuuZaYmHjGjG1O8xZlUnU9JL7/B3VZjdsrX3oNaUCXPin7Hflf7fVvvJj3bv6MW/It9dtW+Kz2PiUmMpZvHIejVitsebyQXHlT9xqKnC87j9dk49GcKccmPK9fv6ZIkSI8fvyYkiU/XlY2NjaW2NjYpH+HhYVhZ2cnbxYhPiEyPJqh9efi7eZP9RblmLZxYIaWoL566jFzB28GYMisdrTslvb7hBRFYfXi4xz8c++eCfM6pLr0dGxsPLNm7ufmjTdoaWkydlxzGjdJeSW22Nh4Vvx2jiOnHwFQpbwjU0e1wCwVn7QHhkayatcVjl5+iqKAnq42PVpUpHvzShh8xo3jrt6BHLv1nOO3nuMdFJZ0XFNDAyd7a6o52VPdyQFnB5tUzUJlFLVa4eV7f266vOXaM3fuvPTkr99apoZ6tKhSgrY1SlEkX+qXov2doijsPv2An7ZfIj5BhXNBGxaPbpPqKm4xsfEMn7KD5698yJfXnNWLumFumrpy5bt33WLN6rOYmOizYdMALNKwp865Y49YOG0v5pZGbD486rOLDWxZcYqtK09TuV4JZv3W57PaSokh9ebw5rEnUzcOpGbL8hnen8hesvPgXhKenClHJjyKotCmTRuCg4O5fPnyv543c+ZMZs2a9cFxebMI8d8Wfr+O83tvkSe/Jb9cmIaJecYtG3V77sXoTr8QExVHqx41GDyj7We1t2nVWbb9fgkNDQ3GzGxLo5ZlU3V9ZGQsUyfv5tEjT/T0tJkx6xuqVEn5jdPvvYOZvvAQr9z80NCAPl1q0KNjtRTPjCiKwtHLz1ix7QJhkYkf2DStXpzBnWphbWWSqufyF9/gcE7cfsHJOy947umXdNxIX5d6ZQpRs5QjVYrbY2aUsUuV0oNXYBiHrj/l0LWn+ASHJx0vXTAvA1tWo0rxAp+VnD948Z5xyw8SFhFD3lym/DS+PQVSOcMQFBLJwHFb8fELpWIZexbP6JCqctUqlZrBAzfy+rUvjRqXZOKkVql9GiTEq+jddgV+PqEMm9SSlh0qpbqNv/N848eAJovR0tZk2/XpmKbDxqb/ZeXYrRzdeJEOQxvTb2aHDO1LZD/ZeXAvCU/OlCMTniFDhnD06FGuXLlC/vz/vkZaZniESL0L+26xYMA6NLU0WXxoLM5VCmdYX+EhUQxvtwIfzyDK1SjCnN/7oqWd9pvTD+64warFxwHSNMgLDY1i0oSdvHjhg5GRHnN/6Ejp0nYpvv7mPTdmLTlMRGQsZqYGzBjTkoplHVJ8/VufYBasP8NdF08g8T6d8b0aUKpw6vdlURSFu6/esfPCAy48fINKnfijXltTk+rODjSvUpzapQqhn4YNTrMDlVrNDZe3HLj6mIsPXUlQqwGoWDQ/Q9vUpHTB1JUL/7u33sGMWrKPd36hWJga8tP49hS1T10Bgb82lY2JjWdgz9p0/SZ1ldueu3gxdMgmFAVWr+lF0VSWPwfYv+06a5aeoEDB3KzdNeSzZ2mHtPoRVxdvxizuTMN2FT+rrU85te0qPw7fROkaRVl0cGyG9iWyn+w8uJeEJ2fK+vUKqTRs2DAOHTrE+fPn/zPZAdDT08PU1DTZlxDi3wV4B/Pz+G0AdBnVPEOTHZVKzaLR25Iqsk1a0f2zkp2Lp56weskJAHoOqp/qZCcgIJxRI7by4oUPZmYGLPmxa4qTHUVR2HXoDhPm7CUiMpaSxW35fVnPFCc78QkqNh66SbfJm7nr4omerjZDOtdkw8yuqU52omLi2HPpIZ3m/MGAZXs4e/81KrVCucL5mNylPicXDmD54DY0rlAsxyY7AFqamtRwdmDxgFYc+6EfXeuXQ0dbizsv39Fr8Q5GrT7Iq/cBaWq7QF4LfpvehaL2uQkOi2LwD7t49NIrVW04FsjFiAENAFi39Qov3vim6vriJWxp0NAZgN/WXiAtn002blUOPX0d3rr68/TB21Rf/09VGiTGc+ucy2e39SmFShUAwPXJuzQ9dyGE+Lsck/AoisLQoUPZt28f586dw9HRMatDEuKLoigKy0ZsJiIkiiJl7ekypnmG9rdlxSnuXHqBnr4O01b1xMQ8dfc5/N2DW64snr4PRVFo1akyXfqm7iZtb+8QRo7YgodHALlymbBsRXeKFrVJ0bXx8SoW/3KKn38/j1qt0KJhKVbM/ZY8uVK2/OzpG296TtvC6t1XiYtXUbmkPdt++I7vWlZGOxUJoH9oBEv3XKTppN/4Yfs53ngHoq+rTYdapdk1tQe/j+lEh9plsDD+vIpd2VEuMyPGdqzLgVm9aFu9JJoaGlx85Mq38/5gyobjBIRGprpNSzNDVk3qSOmitoRHxTJs4R5uPvZIVRvNG5SkdrUiJCSombP0CDGx8am6vnef2ujoaHHvnjt301CxzMhEn3p/3nt2dO+dVF//T1X+LPxx9/JL4lO571JqFSiWF20dLSJCo/B7F/TpC4QQ4j/kmIRnyJAhbNmyhW3btmFiYoKPjw8+Pj5ER0d/+mIhxCcd/v08d889RVdfh/Gr+6CdDtWv/s2100/YseosACN+6EjBEqlfsvWX18+9mTV2B/HxKmo1cGLQ2GapWrrz/n0Qo0ZswdsrhLy25iz/qTv29im7AT4kLIrRM3Zx5PQjNDU1GNqnHuOHNklR2WqVWs3vB27Qf/YO3rwLxNzEgJkDm/LT+G/Ib22e4vgDQiNZsvsCraetZ+vZe0TExGGX25wxHepwcn5/JndtQOHPvKE/p8hracr0Ho3YM/07GpUvgqLA8VvP6ThnMyfvvEh1eyZG+vw0rj1VStkTE5fA2GUHuPfncsOU0NDQYNzgJuSyNObt+yBWbbiQqv5tbMxp3Sbxhv21vyYm1KnVokPi0rPLZ54SGpz6xO/vipTKj7mVMVERMTy96/5ZbX2Kjq429sUTfy68efz5s1NCiK9bjlnPsHr1agDq1q2b7PiGDRvo1atX5gckxBfE44UX62buBaDvjPbYFUn7/Q+f4vnGjyVjdwDQtlct6rUul+a2vN8FMXX4FqIiYyldwYHxc75J1c3h798HMWbUNvz9wylgb8XiJV3IlcKZGbe3AUyatw8vn1CMDHWZMbYVVSukbJ8fL/9QZq45wcOXiaWmG1Utxtjv6mNukvLZl6CwKDadvsPuiw+JiU/8tL10wbz0a1aF6k4O6V4+WqVW4xkYymufAHxDIgiMiCIoIurPP6MJiogiJi4eTQ0NNDQ00PzzS0NTAz1tLfKYGWNtZoK1mTHW5ol/z2tugkMei3TdVBTAwcaShf1b0tPDl7lbz/Dc049Jvx/j3IPXTPy2fqpmuQz0dVgyqg2Tfz7K5XtvGPPjQdZM6UQxhzwput7M1IDJI5oxesZuDhx/QJXyjtSonPKlot26V+fE8Ue8eePHhQsu1K/vlOJrAYo65aNICVteuXhx+sgDOvSokarr/05TU5NK9Upwes9tbp17RtlqGbfkFaBQ6QK8eezJywceVG+e9p8TQgiRI4sWpJXc8CXEh+LjEhjZZD5vHntSsYEzc3YMz7AS1JHhMYzqsBLPN36UqlyQHzYNQDsVm3j+XUhQBKP6/I6XZxAFi9qwZG3vVG2I6PU+mNGjtiYlO0t/7IZlCjc6vXXfjekLDxEVHYetjRkLpnyDQ4GUzaKcvP6chRvOEBkdh6G+LuN71adp9RIpfs3Do2LYcPI2Oy48IObPZUUlHWwY2Koa1UrYp8v3Lio2joce3rzyCeS1TwAvvQJ44xuYlFilJ30dbZzy56FUgbyULmBDGQdbrM2M0639eJWK34/f4vfjN1GpFaxMDZnWvRG1S6VuE9qYuHhGLd7PvefvsDA1ZO20zhSwSXn1tl82nGfngTuYmxmyYUVPrCxS/hy3/HGVDesvkd/OkvUb+qcqqQc4tu8OK+YdJl8BK9btHYqmZtoXd1w9+Zi5QzaTzyEX685MSHM7KXFk/QV+Hr+NCvWdmbdrRIb2JbKX7Dxek6IFOVOOmeERQmSM7UuP8uaxJ2ZWxoxa0TPDkh1FUVg2cReeb/ywsjZj8soeaU52YmPimTFqO16eQVjbmjP3p+6pSna8vUMYM3pbmpKdUxeeMv+nE6hUasqWtGP2hNYp2mclPDKGJZvPceLacwBKFc7L7EHNsc1jlqJ+E1Rq9l5+xK9HrhMSGQNAiQJ5GNSqOjWcHT7r+xYTn8BDdy9uvXnHrddvefLWN6nq2d/p62hTyNoKW0tTrIwNsTQ2xMrYACsTIyyNDTDQ1UEB1IqColYS/yQxgfILjcD3r6+QcHxDI3gXFEpETBz33Ly45/b/ogA25ibULO5As7LFqFAwH1qfMUDX0dJiYMtq1C5VkOmbTuDqHcTIVQfpVKcMo9rXTvHGpfq6Oiwe1YZBP+zipYc/Y5Ye4PeZXTBNYSnv/t1rcfehB6/d/Fmx9iyzJ7RJ8XP4pn1F9u29zTvPIC6cd0kqZpBS9ZqW4rflp3j/NpCnD95SqrxDqq7/u3I1iqCto8V79wC8PAKwTeHyz7QoWs4BgFcP3FEUJUP3AhNCfNkk4RHiK+b6xJOdKxLLOA9Z1BUrG/MM6+vAhstcPfkYbR0tpvzcA3OrtH2Kr1arWTx9H8+fvMPEzIB5K3tglTvl+9P4+oQyZtQ2/PzCKFDAiqU/dk1xsrN9/y1Wb7wIQMPaJZg0vFmK7td57u7LxBWH8Q4IQ0tTgz5tqtKrTZUUb+x59ak7y/ZexNU78ebtgnktGdamJrVLF0zzINAnJJxTj15x8akrDzy8iEtQJXvc1sIUp/x5KGRtRTHb3BTJmws7K7PPSj7+Sa1WcPcP4tFbHx55ePPorQ+vvAPwCQlnz43H7LnxmFwmhjQqXZRmZYtSxt42zUv1nOyt2TqpGz8fvMrWs/fYdfEhLzz9WDaoDeYpXOJmbKjH8rHf0HvmNt76BDNl5RGWjfsmRd9HXR1tpoxsTr9Rm7lw7SVXb71O8dI2Q0M92neoxPrfL7Fzxw3qN3BK1ffdwFCPmg2cOHXoPudPPP6shMfQWJ9iZQrw9I4bj268ydCEx7544vc7LCiSIN/QDP35JIT4sknCI8RXKiE+gaXDNqJKUFOzVXlqt8m4fTWe3nXj90VHAeg/qRUlytmnua0NP5/l8tlnaGtrMWPJt9g5pHzA5ecXxpgx2/D1DSVffguW/NgVS8tPJ15qtcKqjRfYdTCx0lWn1hUY3LteigbfRy49ZdHGM8TGq7DNbcbsQc0oVSRlRRpcvQNZtvcSV5+6A2BupM+gVtVpV7NUipOlvwsIi+TUo1ecfPgi2YwKQB5TIyoXtqNyYTsqFbIjv1XKZp4+h6amBgWtrShobUXbSomzFlGxcTxw9+bUo5ecfvSKgPAotl99wParD7A2M6Z1RSe61yqHpXHqq/rp6WgzpkMdqhYvwOT1x3no6k3vxTv5eVg78uVK2fO1Mjdiyag29J+9g1tP37J86wXGflc/RdcWcshDp7aV2L7vFit+O0fFMvbo6emk6NpWrcuzbet13rzx485tNypVTt2SvHpNS3Hq0H0unXnKoHHN0PmMoiSlqxbi6R03Ht58Q9POqdtfKDX0DHTJV8gaz1c+uD17LwmPECLNJOER4iu155fTvHnsibG5IYMXdMmwfkICI5g/fAuqBDV1WpalVY/qaW7r+P677Np0BYDRM9qk6pPqoKAIxo7ehrdXCLa25iz9sRtWKZhlio9XMf+n45y5lLj3yODedfm27af3+ImLT2DZlgvsO/cIgOplHJk1qFmKlkBFx8Wz5vB1tp27h0qtoK2lybd1y9K/eRVMDFO+dA8Sl6udePCCI3dduP3mHeq/3bZZ3tGWxmWKUr2oPQ65LbLFkiFDPV2qF7OnejF7prSrz/VXbzn54AXnnr7BNzSC387eYsule3SsVppedSuQ2zT1M4U1SjqyYVxnhv68Hw+/YHot3sGKwW1xsrdO0fVF7fMwa1AzJqw4zO7TDyiYz4pvGpRJ0bW9OlfjzEUXfPxC2b7/Nr2+Tdn/B1NTA1q0LMvePbfZseNGqhOeMhUdsbAyJjgwgns3XKlSq2iqrk/WVpVCbP/5DI9uvMnwpWaOTvkTE56n76hYP3VL+YQQ4i+S8AjxFXr70putiw4DMPCHzlhaZ8yn+SqVmgUjtxLoG4ZdoTyMmNchzYOjuzfe8NP8IwB0H1CXBs1TNsAECAuLZvy4Hbx/H4yNjRlLfuxK7hQsg4uKimPqwgPceeCBlpYmk4Y3pXHdTw+6fIPCmfTTYZ6+8UFDA/q1rUaftlVTNCN099U7Zv9xGk//EADqlinEyG9qUSBPym+QB/AODmPn9UfsvfGYkKiYpOOlC9jQpGwxGpcugo15ypcCZgUdbS1ql3CkdglHYuMTuPDMlfXnb/PsnR+bL91jx7WHtKtckj51K2JrmbqbeAvmtWLTuG8Z9ssBXr7zp/+y3Szq14IaJVO2x1vdikUY1LEGq3dfZcnmcxTMn4uyxfJ98joDfV0G967LrCWH2bL3Jk3rO2OTwvu4OnSszIH9d3lw34Pnz70oXjzl5dy1tDSp08iZAztucv7Eo89KeEqUt0dHV5sgvzDeufpjVyhlFevSwtE5H5cO3sHt2bsM60MI8eXLMfvwCCHSh0ql5sfhm4iPS6BSw5I06Fg1w/rasuIUD6+/Rt9Qlyk/f4eBkV6a2nF/48fc8TtRq9TUb1aa7gPqpvja6Og4Jk/ahZurP5aWRixe0gXrFCR44RExjJq+izsPPDDQ12Hh1G9SlOzcc/Gk57StPH3jg4mhHktHt6XfN9U+mexExsQxf/tZ+v+4G0//EPKYG7NsUGt+HNg6xcmOoijceu3JyI2HafrDen4/d5uQqBhsLUwZ0awGxyf1YevwLnxXu3y2T3b+SU9HmyZlirJjRFdW92tHWYe8xCWo2HntIS0WbGDm7tMERUSlqs3c5sasG92RKsULEB0bz8jVBzlw9UmKr+/ZqjKNqhZDpVaYtuoooeEp2xeufs1ilC1pR1xcQtI9YSmRJ48p9RsklqXeueNmiq/7S72mpQG4fvEFMdFxqb7+L7p6OjiVT1yW+vDG6zS3kxKOTvkBcHd5n6H9CCG+bJLwCPGVObj2LM/vuGJorM/wpd0zbDnK3Usv/r+56LwO2BdJ2XKhfwoJjmT6yK1ERcbiXLYAo6a3SXHM8fEqZk7fh8szL0xM9Fm0pAu2+T6dPISERTFy6k5cXnljZmLA8rmdqVz+05/87zv3iKEL9hAcFkVhu1xsnN2NGmU/vfToyhM3Os7ezO5Licvf2tUsye7p31GndKFPP0kS98g5fv8F3yz9g75r9nD2yWvUikKVwnYs79WKY5N6069B5Uy5LyejaWhoULO4A5uHdGb9wA5UKWJHglrN3ptPaLt4M8fvvyA1uy0YG+jx05C2tKxSApVaYfaW02w9ey/FsUzq04gCNhb4BUUwf8OZFF83on99NDU1OH/1BY9dUj570fnbxA8oLl96jrd3SIqvAyhWMh9581kQEx3HjcsvU3XtP5X5cw+eh9fffFY7n+LglDhr9vaFNwkZUBZdCPF1kIRHiK/I+ze+bPrhAAD9ZnUgdz7LDOknyD+MJeMSNxdt0bUadVulbdPAhHgV8ybswtcrhLz5LZm5tAu6uilbiatWKyxacIQ7d9zQ19dh/oJOODrm/uR1wSGRjJy6k1dufliaG7JiXmdKfGIjVpVazYptF1m44QwqtUKTasX5fUYX8lub/+d1kTFxzNh0kuG/HMAnOJx8VqasHtGead0aYWLw6dkwlVrN0XvP+WbJH4zfeozXPoEY6OrQsWop9o/twbqBHWhQsnC6Vlb7O0VRiI6Lxz88EvfAYNwCgvELjyAiNg61OmO3eNPQ0KBSYTvWfd+BTUM6UTRvLoIjoxm/9RjDNx7CLzQixW3paGsxq2cTejVOLNyxdM9Fjt96nqJrjQx0mTukBVpampy//YqzN1OWSBRyyEOLhqUAWLf1aopjdXTMTfkKDigKHD/2MMXXQeJrVuvPktbXzruk6tp/KlUlMRl/esc1VQlmauXJb4meoS4J8Sp83wZmWD9CiC+b3MMjxFdCrVazbMRmYqPjKVenBM2+q5Vh/SwZu4OQwAgcitnQf3KrNLe15scTPLrrjqGRHrOWdcHUPGWVuRRFYdUvZzh37hlaWprMnPUNJZw+fX9FYHAEo6btwt0zECsLI5bP7Yx9fqv/vCY6Jp4Za45x8W7iJ93ft69O7zZVPjkL9czDl0m/H8PTPwRNDQ261i/HoFbVMUhB1a4ElZrjD16w9sxN3P2DATA10KNH7fJ0rVkWU4PUFTb4N+ExsUmJjHtgMG6BwXgEhhASHUNkbCwRsXGo/mOwa6irg5GuDuaGBjhaWVAotxWFcltSKJcljrks0f+MSmF/V94xHztGdOX387f59cxNLjx15e6b94xrXZu2lZxTNCOooaHB8Ha1iEtQse3cfWZsPomlqSFVihf45LXFHPLQq1Vlfj9wg0WbzlK+RH4sUrA303edqnHi3FPuP37LvUdvKV/6030BtGxZlnt33Tlx/BE9e9VK1UakNeqVYNemK9y++oq4uIQUf4DwT0VL5UdbR4vggAi8PQKxTUW1xNTQ1NQkX8E8uD55x7s3vuQrlLaZYiHE100SHiG+Eod/v8CTG6/QN9JjxLIeGbaUbc/aC9y/+go9fR0mLu+Onn7Kyu7+0/H9dzm86xYaGhpMmNse+4IpvzF6+7br7N+XWEJ6/IQWKapoFRAYwchpO3n7PojcViYsn9sZO9v/Xv7mHxzB2GUHee7mi66OFlP7N6FJteL/eY1arbD13D1WHrhCgkqNjYUJ8/o0o1zhTydkiqJw/qkry45eTkp0zAz1+e7PRMdYP233SEHibNEL3wDueLzjtsd7Hnh64Z/Ce2L+x95Zh0lVtn/8MzPb3b3sLssG3R1LdzcKUoKAgWJhYYuJiiiKiqR0dzcsHRtsd3fH1Pn9MbvIOjNbgvr6O5/r4vJ999zPOWdmZ+D5nvu+v7cEMDMyQiKBMrnigRNcmVxBmVxBdkkZ0Vm5cD+mxhpPW2u6NW1CkJ8P3Xw8MTc2avT9GxrIWDCoGwNaNWPZ9uOEJmeybPsJjt6J4qOpg+vt5rZkQhDZhaWcuBnFqz8d4JeXJ+PvUXdmcPaYrpy7GUNMcg5fbjjNx8+NrHONs6MVIwe3Yc/h26zdcpH2rafV63vZo6c/NjZm5OaWEHwlhp696m9A4N/SDTsHS/Jyirl7PZ7OPf3qvfZhjIwNH8zjCb0R/9gED4C7rzNxoSmkxmY+tmuIiIj8txEFj4jI/wPS4rNY++FuAJ5+dwIuTR7P5uT+rQTWf30MgIXLxja6byfsbhKrPtXM7XlqQT+69Qmo99qjR+/x6y+aRvBFzw5g4KBWda7JzC7ixXe2kZpegLOjFd9+NAW3OmZ+RCVm8/KKPWTllWBjacrnL46mrX/toiW3qJR31x/ncngCAP3bNeOd6YOwrodVdVxmLp/uO8uVqCRAI3RmBnVkWs+2jRI6giAQnZXLueh4biSmcjMplZJK7UZ2RwszvO3t8La3wdveFh97WxwszLEwNsK86o+ZoeEDUwZBEKhQKCmVyymTKyitlJNTUkZsTh6x2bnEZucRm5NHYXkFSfmFJN0MYfvNEAylUjp5udPbz4cgP2+aOtg1SpT7uTqw8bmpbLpwi1VHL3M5KpGp325h5axRtPR0qXO9VCrhg5lDyC0q5VZ0Ks+v2sO616biWocLnKGBjHfmD2HOu79z8moUA7pG0b9z3UJk+sSuHDpxj3vhqVy/k0CX9nX3ihkayhg8pDXbt13l0KE7DRI8UqmUHn0DObjzOpfP3m+04AFo2dGbsBvxhN2IZ/DEuq3aG0t1Vic1NuuxXUNEROS/jSh4RET+46jVar55cQOVZXLa9PRn+Kw+j+U6JUXlfPrS76hVmnk7gyc1bgOUk1XER69uQ6lU0WtAC6bNrf/93rgex4ovjwAwdVo3JkzsUuea7NxiFr+9lbSMQlydrfnmwym41uHiFhySwBsrD1BWocDbzY6vloyts1/nSngiy9YfJbeoDGNDGS9P6suEXq3r3NQXlVew+ngwWy/dRalWYyiTMTOoA0/374K5ScMyIoIgEJWVy7GwKI6GRxOXk1fjuLmRER2buNHJy51OXu74Ozk0WExJJBJMjQwxNaqZ2evt513jPvJKywlNy+RCTALnouNJzi/kSnwyV+KT+fz4eVq4ODGtcxtGtg7UOlddGMikzOrbiaAWTVm87gDxWXnM/H47H0wZzPD2tWfgQOMIt+KZ0cz9ajux6bk8v2oPa1+eUucMpUBvZ54a2YXf9l/l83Wn6RDoiY2laa1rHO0tGTO0HTsO3GTt75fo3M67XkJv+Ii2bN92levX4sjKKsLJqf623D36NefgzutcORfJc0vVDSqJe5iWnX3gpzOE3Yhv1Pr64tFMI3hSYjIe63VERP6L/PDDD3zxxRekp6fTsmVLvvnmG3r31l/Sfu7cOZYsWUJYWBhubm689tprLFiw4MFxhULB8uXLWb9+PampqQQEBPDZZ58xdOjQv3Tdx40oeERE/uMc2XCBe5eiMDYz4qVvZyJ9DA3sgiDw3du7yErNx8XTjuc/HN+op/NyuZIPX91GXm4J3r5OvPLe2HqfJy4ui/ff24NKpWbAgBY8Pa9vnWvyC0p5adl20jIKcXOx5tuPpuLsWPvG8dTVKJatPoxSpaZTC0+WvzCq1o2wIAj8evQaqw9cRhCgmZs9y+cOx9et9iybSq1mz7UwvjtyibxSjd1x35ZNeW1UEJ4ONnW+toeJyszhUGgkx8KjScjNf/BzQ5mMnr5N6O7ThE5e7gS6OD42g4OHkUgk2FuYEeTvQ5C/D28JfUnILeB8dDznYxK4lpBCeEYW7xw4yZcnLjC5Y2ue6NIOV+uGWWn7ONmx+fmpvL75CBci4nl98xESs/NZMKhbnZ8rK3MTvntuHDM/30Jceh6vrDnIDy+Mx6AOcTBnrKa0LS41l683n+X9BcPqvM8nJnRh/7G7hEelc/VWPN061l2C6elpT9u2Tbh7N4ljR+8x46leda6ppk1HL8wtTMjPLSEiNIWWbevXO/RnWnTQiLPUhBzyc4qxdXg8VucevtWCRyxpExFpCNu2bePFF1/khx9+oGfPnvz0008MGzaM8PBwmjTR/t7Hx8czfPhw5s2bx6ZNm7h06RKLFi3C0dGRCRMmAPD222+zadMmfv75ZwIDAzl27Bjjxo3j8uXLtG/fvlHX/TuQCI/TXuVfRlFREdbW1hQWFmJl1bAhdSIi/4sUZBfxdLdllBSW8cxHkxm3YOBjuc6Z/bf5fMnvyAykfLXtWQIauYFa9dkhDmy/hoWVKd9tmI+bZ/1c5PLySnl20TqyMoto27YJn34+pc5m7OKSigdubE4OlqxaPq3OAZD7zobw6dqTqAWBgV39eW/BMAwNZHrjq13YTt/R9K6M79WaVyb1xaSOe4vNyGXZ9uPcS9I80fZxsmPpmL70CPCqdd3DyJUqjt+PZsv1u9xMSnvwc0OZjN7NvBjawp9+AU2x/At9P4+L/LJy9twJZ8v1uyTnFwIgk0gY0sKPuT070dKtYaWSKrWabw9f4rezmr6uid1a89a4/nWKF4ColGzmfLmNskoFTw7owMsTg+pcEx6XwZz3fkcQ4Me3J9M+wKPONavWnmH7vhu0b+XJtx9PrftFAcePhfDZpwfx9LTjt/XzG/SQ4ZM3dnDueChPzgviqQX9673uzzwz9EuSYjJ5b81suvZv0ejz1EZhbjFTAl4GYH/K9xg1si9Q5H+Hf/N+rfreMvOy/tZ7KyoqwtnOqUHvSdeuXenQoQOrV69+8LPmzZszduxYli9frhX/+uuvs3//fu7f/8PFccGCBdy9e5crV64A4ObmxltvvcWzzz77IGbs2LFYWFiwadOmRl3370DM8IiI/If55f1dlBSW4dvak9FP93ss18hOL+CH9/YAMO3ZgY0WO6eP3OPA9msAvP7h+HqLncpKBcve3klWZhHuHra898H4OsVOeYWc1z/cRXR8FrbWZnz9weQ6xc7mwzdYueU8AGP7tea1WQNqzYYkZeWz5Mf9xKXnYWggY+mUfozr1brWayhVatadvcEPx4NRqFSYGxvx3NDuTOnRFkOZfmH1MGkFRWy7GcLOW6HklmpMB2QSCf0CmjK0pT99/Xz+krnB34GtmSlzenRkZrf2nIuKZ33wba4mJHM4LIojYVFM7NCKJQN6YWtee7lYNTKplCUje+Nma8Une0+zMziE3OIyPp8+vE6nOH8PR96fOYRX1xxk86lbdAnwpHfr2jMwLZq6MKZva/aeCWHl7+dY+94TdYqRSaM6suvATW6HJhMdl4lf07pFXa/e/ny9woDk5DxiYjLx86u7R6maDl2bcu54KLevxf0lwePXyp2kmExiQlMem+CxsrPAxNyYitJKslPzRKc2kX8F04PfwdC88UYrDUVRqumxLCoqqvFzY2NjjI21/06Xy+XcvHmTpUuX1vj54MGDuXz5ss5rXLlyhcGDB9f42ZAhQ/j1119RKBQYGhpSWVmJiUnNqgZTU1MuXrzY6Ov+HYhzeERE/qOEXI7i5NYrSCQSnv/ySWS1ZCIai1qt5uul2ykpKse/jSdTGrlxSozL4puP9gPwxNNBdKlnE7ZaLfD5Z4e4f18zWPST5ZOxsqp9EyxXKHlr+V5CI9KwMDfmq/cn4VnLPCJBEPhxx6UHYmfGiE4snT2wVrFzMTSe6Z9qSqEcrM35+aVJdYqdyLRsnli5hW+PXEKhUtEr0Ju9rz7F9N4d6iV2QtMyeW7rfgZ+u5afLlwjt7QMJ0tznuvbjdMvPc2qqaMZ2TrwXy92HkYmldI/0Jf1syayd8F0RrQKQAB23Apl6Kp1bLtxD5VaXe/zTe3Zlq+fGoWRgYwzYbG88Ns+5Mq6h1kOaO/HtH6aUo33N54gr6hu97r5EzQW4+FxmZy6VvdsHmdHK4J6aMw5dh6o3+BTMzNjulcNAD19Krxea6ppXzVHJyI0ldKSigatfZhmrTTZq+jQ1Eafoy4kEglOHprvaGayOItH5P83np6eWFtbP/ijL2OSk5ODSqXC2bnmAwJnZ2cyMnT3w2VkZOiMVyqV5OTkABoBtGLFCqKjo1Gr1Zw4cYJ9+/aRnp7e6Ov+HYgZHhGR/yDySgUrX9aklofO6EVgPXoCGsOhzVe4fSkaI2MDXv1yKgaGDRdV5WWVfPjqNiorFLTv2pTp8/vWe+2G9Rc4e+a+ZtbOB+Px8Kg9K6RUqXn/y4PcuJOIqYkhny+bQDMf/XbXarXAVxtPs/OkZsDjosm9mDlKvxHCn/t12vm68dm8ETha67dEVihV/HzqGj+fuoZSrcbS1JjXRwcxulOLepUohadnsersFU5Hxj34WXcfT6Z1bku/gKb1zgz92wl0ceSricOZ1rkNHxw6Q1RWDu8ePMWOW6G8O6I/rd3rl90Y0LoZa+aPZ+Eve7kSlcTrm4/wxfQRdZa3vTCuF9cikohNz+WDTSf4euHoWn8/9tbmTB/RiZ93X+GH7RcJ6tis1vJHgEmjO3L6YgQnz99nwcw+2NqY1/l6+g9syblzEZw5Hc68+f0euOXVhbOrDW6edqQl5xFyK7FBTogPUy14YsJSGrW+vjh72pMUmS4KHpF/DZu6ffj3l7TxE8nJyTWuqyu78zB//ntKEIRa/+7SFf/wz7/99lvmzZtHYGAgEokEX19fZs+ezW+//faXrvu4EQWPiMh/kO3fHiU5OgNbJyvmLBv/WK6RHJvFr59prKPnvD4CjwbMyalGEAS++Wg/yQk5ODhZsfTjifV2jDp1MoyNGzQT6l9aMpR27Wrvb1GrBT5fdZQLwdEYGsj4+I2xtArUbyOtUqv5+OfjHLoYjkQCrz41gAkD2+qNVyhVfLDpBIeuamqfJ/VpwyuT+ta6yU3MzufVTYe5n6qx2+3X0pd3JvSv18yYiIxsVp29wskIzcBTqUTCyNYBPNO7C76OtQ9LrS8qtZqs0lJSC4tIKSwkraiY1KIiyhUKlGr1gz+qqv8aGxjgZG6Oo4U5TuYWVf81x93KCnvz+g2NrYtOXh7sfuZJfr9+h5VnrhCalsnkn7cwuWNrXhvcp16zfDo29WDl7NEs+mUvJ0NieG/HCT6YPLhWsWBsaMDHc4Yx47MtnA+JY/fFECb0blPrdZ4c1ondp+6RmlXI7lN3mTKkQ63xLQPcaOHvSnhUOvuO3mXW1B51vpYuXZpibm5MdnYxoSHJtGlASWmHrr6kJedxKzi20YLHt7kbEomE3Mwi8rKLsKvD9KOxOHtqPtOi4BH5t2AiM8ZE9vdlzOVV17KysqqX0HJwcEAmk2llVbKysrSyL9W4uLjojDcwMMDeXvMddHR0ZO/evVRUVJCbm4ubmxtLly7Fx8en0df9OxAFj4jIf4zk6HS2faOxZl7w8RQs6/GUuKGolCq+eGWLJivT049R0+vemOni4M7rnD0WilQm5c3lk7Cxrd+9Rkam88XnGrE1eUpXhg3XL0Sq+WnjeY6eDkMmlfDea6Po1M5bb6xaLTwQOzKphGXzhzK0Z3O98cXllbz60wGuRSYjk0pYOrV/nZvhQ7ci+GDXScoqFVibmfDWuP4Mbedf5xOw+Jx8Vpy6yImqIZ4SYETrQBYFdaWpQ/36nnQhV6kIz8ziTno6t9PSCc3IJK2oCEUDSsZqw83KkvZubnRwc6WDuxuBjo6Nzj4ZyKQ81a0Dw1oG8OWJC+y7d59tN0O4kZjKqqmj8XGofWAsQDe/JnwxYzgvbzjIvhvhWJuZ8Oro2g0J/D0ceW5MT77edZ6vdp6jc0ATmjjZ6I03NTFk/oTuLF97kl/3BjOiT0ssTGvfIE0c1ZEPvjrI3iO3eXJCVwzryJoaGRnQu08AR4/c49Sp8AYJnvZdm3Jw53VuXY2t95o/Y2pujEdTR5Jjs4gJTaVLv8creLJEwSMiUi+MjIzo2LEjJ06cYNy4cQ9+fuLECcaMGaNzTffu3Tlw4ECNnx0/fpxOnTphaFjTLMTExAR3d3cUCgW7du1i8uTJjb7u34EoeERE/kMIgsAPS7eikCvpPLAVfcZ2eizX2fnzOaJDUrCwMmXJZ1MaZXUdH53JTys0Q0rnPj+Qlu3qt1HLzy/l3Xd2oVCo6N6jGfPm123GsOfwbbbs1hgivPb8UHp31T9sUa0WWL72xAOx8+GiEQzoqr+nKKughOdX7SE6NQczY0M+mzeSni299caXVSr4dN8Z9lwLA6BjU3c+fWIYLja1W/qWVFTyw/mrbAy+jUKtRgIMaxXAs0FdG5XRkatUBCclczEhkdtpaYRlZiFXqbTiDKRSXC0tcbe2wsPKCjcrKyyMjTCQSjGQSpFJpRhW/bdMriCrtITsklKySkvJLi0lq6SUrJIS0oqKSSuK5FBEJAAmBga0dXVhqL8/I5sHYGtaPwOCh3G0NOez8UMZ174lr+0+QmxOHlN+2cKKiSPo1axuR7sBrZrx4ZTBvLnlGBvO38LL0ZbJ3evI2vTvwIWQeG5EJfPp1tN8//y4WkXqyD6t2HL0Fglpeew5dY8ZI2ufT9W3hz/frzUnN7+UyzdiCepedz9bv37NOXrkHpcvRbH4xSH1Lmtr09EbgOSEHAryS+v9wOHP+LZ0Jzk2i/iIdLr00/9g4K/gWFWump2aX0ekiIhINUuWLGHGjBl06tSJ7t27s2bNGpKSkh7M1XnjjTdITU1lw4YNgMaRbdWqVSxZsoR58+Zx5coVfv31V7Zs2fLgnFevXiU1NZV27dqRmprKe++9h1qt5rXXXqv3df8JRMEjIvIf4tKh29w+dx9DIwMWLp/6WOplE6My2LTyOAAL3hmDg0vt7ma6qCiX88mbO1DIlXTp6ceEemaIlEoVH76/l+zsYjw97XjjzdF1bu4uXYvh259PAfD0k70Y1r+V3lhBEPhi/Sn2nwtFKpHw/sLhtYqd2LQcnlu1h8z8EhyszPj22bE0b6I/ZR+dnsOrmw4Rm5mHRALPDOzKMwO71do/olYL7LkbztcnL5JT5boW5OfDK4N64edU+yyfP1Mql3MuPoET0dGciY2nRC6vcdzW1IR2bm60d3WlrasLPnZ2OFuY/+XZPCVyOSHpGdxOS+dWWhq309IorKjkanIKV5NT+OTMWfr5NmVcyxYENfXBqIGZn24+nuya/yTPbzvAnZR05m/ew+uD+/BUt/Z1fgdGdWxBen4x3x29zPI9Z/BysKGrn37xLZVKePvJgUz+cAPB9xM5cSuKwR31l4MZyKTMHNWF9386ypajt5g8uD3GtbgIGhjIGNyvJVt2X+Po6bB6CZ627bwwNTUiL6+U6OgMAgJc61wDYGVtRhMfR5Lis7l/L5nuQXUPZdWFV9Vg0KTHOCfHrmoYcF5m4WO7hojIf40pU6aQm5vLBx98QHp6Oq1ateLw4cN4eWkeCKWnp5OUlPQg3sfHh8OHD/PSSy/x/fff4+bmxsqVKx/M4AGoqKjg7bffJi4uDgsLC4YPH87GjRuxsbGp93X/CUTBIyLyH6GirJI1b28HYOLzQ3CrpRm/saiUKlYs3Y5SoaJLv+b0H1t7T4I+1nx9jKS4bOzsLXi5AcNF1/x0hrt3kzAzM+KDjyZibl57eVBEdAbvf3kQtVpg5KA2zJjUTW+sIAis2HiG3afvIZHAsmeGMKib/o3szagUXvpxPyXllXg727Lq+XG42esXf7uvhvLJntNUKlU4Wpnz6RPD6NLMs9b7v5OczsdHzhCSptlIetvb8saQIIL8fWpd9zCVSiVHo6I5GBHJpYTEGlkcR3Nz+vs2pZOHO+3dXPGysXksItnCyIjuXk3o7qUREmpBID4vn/PxCewJCyc8K4vj0TEcj47B1tSEkYGBTG/fDl/7+pfoOVqas2HWRN49eIo9d8JZfuwckZk5vDeyP0YGtf9TN29AF2Iz8zh8O4IlGw6y+YVpeDvqL4tr4mTDrCGdWXMomC93nKNHC+9aS9UGdwvgx52XyMwt5tDFcMb3rz2LNKxK8ATfjCO/oLRO8wJDQxmdOvtw4XwkwVdi6i14AFq08fzrgsfv7xA8NgDki4JHRKRBLFq0iEWLFuk8tm7dOq2fBQUFceuWfqfIoKAgwsPrdoWs7br/BKLgERH5j7Bj5TGyUvJw8rBjyuKhj+Uau349T9S9ZCysTHnhowmN2hxfPB3OoV2aAZCvfDAeG7u6G/QBTpwIZdfO6wC8/sYomjSpvYwrPbOQpR/toqJSQZf23ixZMFDv/QqCwMot59l+4g4Abz89hGE99c8UOXU7mjfXHkGhVNHO142vF47B2txEZ6xCpeKzfefYdlnj9NYzwIuPpw7F3lJ/E39JpZzPj59n+80QAMyNjFgU1JUZXdtjVE978cT8ArbevcfO0FDyy/+wHfaysWGwXzMG+TWjnZsr0n/ANUcqkeBrb4evvR2zO3UgMjubvWH32Rd+n6zSUjbevsPmO3cZ36oFL/TogZtV7eV+1RgZGPDJmMEEOjvy2fHz7L4TRlxOHqunjal1Zo9EIuGDyYNIySvkXmI6i3/bz5bFT2BmrH/A5ewhnTlyLYLk7AJ+PHiFVyb11RtrYCDjyWEdWbHpLJsOXWd0UKtas3reTRxo7ufK/eh0Tpy/z+TRdZemduvejAvnI7kaHMPMWb3rjK+meRsPju67xf2QxrusNakSPMmxWajV6kaVuNZFdYanrKSC8pIKTC10f99EREREdCHO4RER+Q+QnpDN9u+OAjD/w0mYmD1655ikmEw2faspZZv/1ijsnRteypaVUcjXH2rm7Uya2ZOO3XzrtS46OoOvv9IYMTw5vQe96pjTU1xSwWsf7CKvoAxfb0fef200BrUIhR93XuL3IzcBWDp7ICP7tNQbe/jafZb+cgiFUkX/ds344YUJesVOQWk5C9bsYdvlu0gk8PzQHvwwd1ytYudKXBKjf9j4QOyMb9eSo8/PYm7PTnWKHZVazcmYWObs3M2AX9by8/Ub5JdX4GppyfM9unF41lOcfHo2r/ftQwd3t39E7OgiwNGR1/v24cKCeaydOJ7+vk1RCwI7Q8IY+Mtalp85R355eb3OJZFImNm9A2ueHIeViTF3UtKZtWEn+aW1rzc2NODbWaNwtDInLiuPz/efrTN+6VTN3KmtZ+4QlZJda/zooNZYW5iQmlXImevRdb6Oof01n8Gjp0PrjAXo0kXzXYqMzCA3t6ReawBaVJkcRIamolRo93DVBxdPewyNDKisUJCZ8nh6bMwsTTCpyuiKZW0iIiINRRQ8IiL/AX56ezuKSiXt+gTSc2TjysxqQ6XSDBhVyJV0Cgpk4PiGmyGoVGo+f2eXZkhpCzdmLqzfkNLCwjLeW7abykolXbo2rfPptVyh5O3le0lMycXR3pLPl03AvBYBuPHQddbt1xgavPJUf8bVUm6052II76w7ikotMLp7Sz6bNwITPf0YMRk5TP32d67FJmNmbMi3s0Yzf2BXvT1HpZVyPjh0mtkbdpFWWISHjRXrZ07kk7GDcbSsvaRJrlKx9e49BvyylgV79nE+PgGA3t5e/DhuDGfmz2Vxzx74Ozr8o3MQ6kImldLHx5s148ey/YmpdPZwR65S8euNm/Rb8ys/XLlKhUJRr3P1aubFlrlTcLQwIzIzh1kbdlJQVvuATQdLc5ZPG4pEAruuhnL0TmSt8d1beDGwgx9qQeCb3edrjTU1MWTyYM3w0g0Hrz2YbaGPAb0DMTSQEROfTXRc3aVidnbmBAZqStmuBtffdc3Dyx4LSxMqKxXEN7IkTSaT4unrCEBi9GMsa3MS+3hEREQahyh4RET+x7l1Npzgo3eRGUgfm1HBgY2XiLiThJmFSaNL2XZuuETIrURMzYxY+slEDA3rrqhVqwU+XX6AjIxC3NxsePOt0bXO6REEgRWrT3A7NBkzUyM+XzYeR3v95VCHL4azausFAJ6b2ptJg9rpjd129g4fbj6JIMDkoLYsmz5IbzP/ufA4pn+3jdS8ItztrNj03FT6tdSfzbqWkMKY1Rv5/bqm7O2Jzm3Zt3AGXX1q7/GpFjoDf1nL28dPklJYhI2JCU937sjJp2fz26QJDGzmi8FjKDF63HRwd+P3qZP5deI4mjs5UiKXs+LiJUau30h4Zla9zuHraM/6mZMeiJ6FW/ZSoVDWuqarXxPmDegKwEe7T5NbXFZr/Atje2FoICP4fhI3opJrjZ00sB0mRgZEJWZzK6L2EjIrS1N6VmVtTl2IqDX2wb13awbA9etxdUT+gVQqJbC1ZnhoxF8oa/P01ZS1pcTV73fTGKrL2vKzih7bNURERP6biD08IiL/wygVSta8ozEqGDmnL14Bbo/8GpkpeaxfoSmXm/v6cBxdbRp8jtjIdDb8eAaAha8Ox92zfjbKW7dc4drVOIyMDHjv/fFYWtZuXbzz4C0OnwpFKpXwwWuj8fXWb9xw5V48H/2iKdF7cnhHZozQbxe86dQtVuw8B8CMgR15cXxvnaJPEATWn7vJikMXEATo1NSDFTNH6u0fkStVfHXyIuuDNQ2ibtaWfDR6ED18a3eyqVQq2RUaxo9Xr5FWVAxoDAjmd+nM1LatMTXU33tSX0rkcrLKSsgpKyOnvJSc8jKyyzT/RQBDmRQjmQxDqeaPsUyGrakpTW3s8LWxw8HU7C+Lb4lEQpCPD729vTl4P4LPzp0nIb+AiZu38Hb/vkxr26bOazR1tGPtUxN4cu12bien88quw3w7eWStznMLBnXlXHgckWnZfL7/HJ89OUxvrIejDWN7tGLH+busORRMJ3/9ItXa0pShPZuz90wIu0/dpWPz2gVt354BnL0cxYXgaJ55qk+dr7V9By/Wr7vAvXtJDZpq3izQlRuXY4iNyqg7WA9uXprvdHrS45uTY2Wv6fcryqt/yZ6IiIgIiIJHROR/moNrz5FwPw1LW3OmvzrqkZ9fEARWvr2LijI5rTr7MHRK1wafQ16p4LN3dqNUqujRN5DBo9rVa93dO0n8tlZTJvT8C4PxbVb7hOZrt+P5fq1GVC2a1ZcuHfQ7mYXFprP02wOoVGqG9mzOc1P66I1dd/w6K/dcBDSN6s+N6alzI6lSq/l071m2VpkTTOzWmjfH9sNQT99NWkERL+04xN1UzSZzcsfWvDaoNxYm+svvBEHgUEQkn527QHqxRug4mZszv2tnprZpjUkjhU5BRTkh2ZmEZGcSmp3JvewMUor/2lN0SyNjfG3s8LW1I9DOgaAmPvjZ2jdKBEklEka3aE5vH29eO3KMM7FxLDtxiuCkZD4eMghL49p71vycHPhh2mjmbNjNyYhYPjp8hmUj+uu9F0OZjPcnDeSJlVs5fDuCER0C6dNc/+dp9pDO7LkUwo2oFG5Gp9DRz0Nv7Pj+bdl7JoSzN2LILyrD1kp/P1fXDj4YGshITssnMTkX7ya125AHBLhibGxAQX4ZSUm5eHnVz7bc119TCvdXBI9rk79B8FTNCSrKL31s1xAREflvIgoeEZH/UfKzitjw6T4AZr89DstGDg2sjZN7bnLrYhSGRgYs/mRSo9yXfvv+FImxWdjYmbP47dH12vDm5ZXy8Uf7UKsFBg1uxbDhtdv4Jqfl894XB1CrBYb1b8Wk0R31xiZl5LPkq71UyJV0be3F208P1ttXs/boNVbtuwTA/BHdeGZEN533L1cqeXPLMY7djUIigVdHBTG9t/4ZMOei4nltz1EKyyuwMjHm07FD6B9Yu4FDZHY27586w7VkTdmRk7k5C7p1YXLrVg0WOmUKORdTkjiVEMul1ES94sbC0AgHMzMcTM1xMDXD0cwce1MzDKRS5ColcrUauUql+d8qFVllpcTm55FSXEixvJI7WencyUoH4OMr5/C0tGaAd1P6e/nS1c0DY1nD/gmyNTVlzbgx/HrjJl+ev8jhyChCMzNZOXokrZxrF8SdvDz4YsIwXtx+kC037uFsZcmCPl30xrf0dGFGnw6sP3eTD3edYu8rT2FuYqQz1sXOkrE9WrHzwj3WHArmpxcn6j1vgLcTgT7ORMRncvhiOE8O198PZ25mTMe2XgTfjON8cHSdgsfIyIAWLdy5fTuRu3eS6i94AlwASIjJRKVUIaunE+DDuHiKGR4REZF/L6LgERH5H2Xth7spK67Ar60XQ6b3euTnz8suYs3HGke16YsH4+Hj2OBz3Lkez57fgwF46Z0x9ZrkrlKpWf7xfnJzS/DycmDxi0NqFUklpZW88fFuSkoraRngxsuLBumNzy0oZfHnuykoLifQx5nlz4/Sm4HZdOrWA7GzaHQPnh6mO7tVWiFn8fr9XI1OxkAm5ZOpQxnWXvf8HqVKzcozl1lzUWOv3crNmW8mjcDDVr/jXVFFBd9eusKm23dQCQImBgYs7NaFuZ06NkjoZJaWcCoxlpMJsVxKSaJSVbOXxdvahlaOzrR2cKa1owstHZ2wNm6c9W+FUklCYT5xBXnEFuRxMyONy6lJJBcXsi7kNutCbmNuaEgfT2+mtWhLbw+vemd+JBIJT3fuREd3NxYfOERSQSGTNm/lrX5BPNmuba3nGdLCj7eG9eOjI2f45vQl3KwtGd22ud74RYO7czIkmtS8Ir47eomlY/vpjZ09tDN7L4dyPTKZW9EpdKglyzOmb2si4jPZdzaEJ4Z1rPWe+3TzI/hmHBeCo3lqcne9cdW0bddEI3juJjF6TP0MTFw9bDEzN6astJKk+Bx8/GoXjzrPUZXhyUoraLRoqgsrW1HwiIiINA5R8IiI/A8Sfj2WE1suA7Dos2m1NvI3lh/e20tJYTnNWrozYa7+ki99lBZX8OW7exAEgWHjOtKtj/4hng+zedMlbt1KwMTEkGXvjcPUVPdTddCIow++OkhSSh6O9pZ89MYYjPSYIZSWy3npyz2kZRfi4WTNipfHYq7n3Dsv3HvQs7NgZHe9Yie3uIyFv+zhfmoWZsaGfDNzFN39dfffZBWX8PLOI1xP1GRonujclqVD+ugdiqkWBHaHhvH5+QvklWkslYf4+/Fm3yDcra30vicPU6FUciQuit/D7nI9I7XGMQ9LKwZ6N6O/V1PaOrk0WtzowsTAgEB7RwLt/xDJZQo5l1KSOJUYy6nEOLLLSjkSF82RuGgC7Rx4um0nxvg1x1BWv41yezc39j81ndePHudUTCzvnTxNamERrwXp7q+qZnrXdmQUFfPLpRssO3CSABdHApx1Z0LMjA1ZNnEgz6zZze+X7jC8fSBtvHQP9XS1s2JMj5bsuhDCmkPB/FhLlmdw9wC+3XyWxPR87kSl0j5Avzjq2cUX6WoJkbGZZGYX4exY++++bZXN9N079e/jkUql+Aa4EHIrkej7aY0SPHZOlhgaGaCQK8lKK3gggB4lVnZVJW2i4BEREWkg/3vWPSIi/88RBIGf3toGwOAnetC8U9NHfo3gU+FcOhaCVCblxeWTGvW09scVR8nOLMTV3ZZnlgyp15q7d5LYsF7TL/PikqF4e9dekrN2yyWCb2pMDT55cyz2trqHmKrUapb9cJjIxCxsLU355rXx2FvrzjYduRbB8i2nAJg5uBPzhusWO6l5hcz8fhv3U7OwMzdl7YKJesVOSGoGE376neuJKZgZGbJi4nCWjeivV+ykFBYyY9sOlh49Tl5ZOb52dqybNIHvx4yql9iJyc/lg0tn6LrhR146dZjrGalIgHZOrrzapRfHJs/kwpPzeK9Xf/p4ej9SsaMPM0MjBvk049O+Q7j61AIOTJzO7NYdMDMwJCIvh1fOHKXvll/ZFHaHCmXtTmrV2Jia8uPY0bzSR5Ph/Pn6DT49e75Oy+clA3rRy9eLCqWSV3YeRl7L9Xr4ezG6Y3MEAT7cdQq1Wv+5Zw/pgoFMyrXIZMIT9ffDWJgaM7h7IAAHz4fVeq+2Nua0CnQH4NK1mFpjAQKbu2FoKCM/v5SUlLw646vxa64xPImJSK/3moeRSqW4eNoBkJH8eMraqst2i/LEHh4REZGGIQoeEZH/MS4dvEXkrQRMzI2Z9da4R37+ygoFP32k6Q0aP6c3vi3cG3yO65ejOb7/NhKJhFfeH4dpPQahFhWVs/yT/QgCDB3ahkGDWtUaf/FqDBt3aMrlXnt2CAHNXPTG/rDtIhfvxGFkKOPLJWPxdLbVGXchJI531x9DEGBSn7a8MLaXzifkcVl5PPX9dhJzCnCztWL9c1No6an7+sfDo5nx2w6yS0rxc7Rn5/wnGN5Kd7ZLEAS23QthxG8buJqcgpmhIa8H9ebArBn08q7duU2lVrM/OoLJe7cycOtvrL13k8LKCtwtLFnSuSdXZjzD3glP8mzHbgTYO/6j83ikEgmtHV14t1d/rjz1DK93642DqRmpxUW8ff4kQb//wvaIkDqFC2hK3BZ07cJHgwcC8OuNm3x76Urt15dK+GL8MOzNzYjOzuW7M7XHvzI6CAsTIyLSsjl+L0pvnJu9FYM7aobibjt3t9ZzDuupKaU7dyMGhbL2gZ/dOmoealy/k1hrHGj6ePz9NZ/FiAaIF+8qU5DE+NoHqNZGtYNjTsbjmZNjYa0xeCgrrt8QWhEREZFqRMEjIvI/hEqp4reP9gIwYeGgB3MpHiU715whIzkPe2drnnhuUIPXlxSX882Hmt6fsdO60qp97Rt10Gz0v15xlOzsYtw9bHnuhdqvm5qezyffHgZgwsgODO7bQm/swfNhbDp8A4C35w2hVTPdJUk3o1J47eeDKNVqhnUJ5PUp/fSKnTmrd5BVWIKvsx0bnpuCt6O2gBIEgZ8vXueF7QepUCrp08ybLXOn0NTBTuf1M0tKmLd7L28dO0GpQkEnd3cOzJzBvC6dMaqlzEulVrM3KpxBW3/jhZMHuZaegkwiYZB3M34bPp7zT87jhU7dcbHQP4/on8Ta2ISF7btycbom4+RqbklmaQmvnTnG3CN7yCytX/nS1LZteKd/XwBWXQnmx6vXao23NTflg1FVIunyTe4k6xcHtuamPNVHY4Tx/bErKFVqvbGTg9oBcOx6JPkl+jfmbQPcsbc2p7iskmuhtQuZzu29Abh1LxFlHeIIIKBqAGnE/bQ6Y6vxaqopP0yKbfwcHQcXzd9HOZmPZ06OWZUtfVlx7QNkRURERP6MKHhERP6HOLb5EqmxmVjbWzD+2YaLkbpIT8pl+08aa+f5b47C1LzuzMyf+WnFMXKyinBvYs+sRQPqtebY0RDOn4tAJpPy1ttjau3bqaxUsOyz/ZSUVtIq0I1nZ/fVG3snMpXla08AMGdsV4ZUlRH9mfDETF5cvY9KhYo+rZvy3lO6nduqxU5ucRkBbo78tmgyztbaZXRypYq395/gq5Oa8rzpXdrxw7QxOi2nBUHg4P0Ihv+2nrNx8RjJZCzt24fNUyfhZWuj97U9LHRePHWYuMJ8bE1MebFTDy5Nn8/Pw8bSz6tprfNm/k2YGBgyq3UHzj45l9e69sZIKuN0YhyDt61jb1R4vbI9Mzt2eFDe9uX5i6y/eavW+AGBvoxuE4haEFi69xjlcoXe2Bl92mNtZkJCdj6Hb+sfBNrax4VATyfkShX7LofqjZNJpfTv4gfAqWvRtd6nn48T1lamlFcoCIusO2vTvKo87X4DBE+TKlOSvNwSigprH7aqD/tqwZNR0Kj1dWFmqSm9LCsRBY+IiEjDEE0LRET+R6goq2TT5wcAmPbyCMzrGMLZGH76aD/ySiXtejSjdx1W0Lq4fumPUrYly8ZgUotwqSY1NY/vVmoGgM6e24eAAN0ZmGpW/nKa6PgsrK1Mee/V0Rjom3OTVcjr3+5HqVLTv7Mf88b10BmXnF3A86v2UFohp6OfB58+PUJn4/yfxc7Pz0zQOVC0oKyCF7Yf4FpCClKJhDeH9mV613Y6r10ql/PO8ZPsv6/ZQLdydubz4UPwd9Dfu6QWBPZH32fljSvEFeYDYGtiyry2nXiqVXssjOp+z2tDqVaTUJRHbFEeRfIKShRyShSVlCjkFCsqKVXIMZEZYGNsip2xGbbGJtiamGFrbIqnhTXOZn8tk2QsM2BRh64M9Pbl5dNHCMnO5MVThzkSF81HfQbiaFa709+Crl2oUChYdeUqH54+i4mhIVPatNYb/9awfgTHJ5OQm883py/xxtC+OuMsTIyZ068TXx+6yA/HrzCsfYDOz4lEImFy37Z8sPEEO8/fY8bAjnpF54Cu/uw4cYdzN2NQKAfqdQyUSiV0bufNyfP3uX4ngbYt9ZscADSvKkONjclELldiZFT3P/Vm5sY4uViTlVFIUlx2vTKzf6Y6w5Ob8XgyPKYWGsFTUVqJSqV+LGYtIiIi/01EwSMi8j/C3jWnycssxMXLgeEzG+6aVhfBJ8O4ejocmYGUhcvGNrjHo6S4nG8+algpm1Kp4pOP9lNRoaBtuyZMnlz7YNMjp0M5cPweEgm8+/JInBx0b65Lyit5ecXeB/bT7z4zVGfGJr+4jOe+20N+STmBnk58vXA0Jjo2h/UVOyn5hTy9aQ8JufmYGxnx9aTh9PHTPbAyJjeXZ/cdIDY3D5lEwrPdu7GwW5daXcruZqWz7MIp7mZpGuJtjE2Y365zo4VOYWUFt7JTiSjIJqogm4j8bGILc5Gr6y6b0oermSXtHd1o7+BGOwc3Wju4YtLAeTsA/nYO7B73BKtvX2PlzSsci4/menoKnwQNZmhTv1rXLu7Zg3KFkl9v3OTtYyewNTFhsL/uNdamJnw0ehDzN+9lQ/BtBgY2o7O3bkExtUc7Npy/RWpeEXuvhzGpm+6HAkM7BfLt7guk5RZxKSyBPq11G4u09XPHwcacnIJSroYm0qudfgOSB4LndgJPP1m7Db2LizU2NmYUFJQRHZ1ByzoEUjVevk5kZRSSGJfVOMHjXJ3heTw9PNUZHoDykooHPT0iIiIidSEKHhGR/wEKc4vZsfIoAE8tHYORccMGTdZFRbmc1R/sBWD8nCCaNGu4Le3P3xxvcCnb5k2XiYhIx8LChKVvjKr1iW1CUg4rVleVp03rSad23jrj1GqBd384QlxqLg425nzx4mhMdLxflQolL/24n+TsAtzsrVj57FgsTLVLzuKz8phbD7ETm53L7A27yCouxc3aktVPjNVrd3wkMoqlR45RqlDgbGHOylEj6eih3xwir7yML65eZOv9ewhoBoIubN+Fma07NEjoCIJAWF4m59LiOJMSx+2cVFQ6SsXMDAzxs3bAzsQMC0Ojqj/GWBgaYW5oRIVSSX5lOfmVZeRXVpBXWUZ+RTkppYWklxWTnhjJ4cRIAIykMto5ujGxaStGejfHzLD+92sok/FCp+4MqMr2RORms+DYPt7t2Z/ZbfTPmJFIJCzt24cyhYItd+/x6uGj+Ds64G2r26yij58PE9u3YuftUN7ad5wDi57CWIe9uZmxIfMGdOHTvWf56cRVxnZuqVOgmhgZMLp7SzaevMnuCyF6BY9UKqF/Zz+2n7jD6atRtQqeTu00AiQiJp3ikgosLfQ760kkEpq3cOPK5Rgi7qfVW/A08XHk+qVokuIaZ1xg76xxEMzNfDyCx8jY8IH1dVlxuSh4RERE6o0oeERE/gfY/OUhSovK8W3tSd8JnR/5+bf/dIastAKc3Gx44vmBDV4fcjuRo3s1/RIv1bOULSoqg82bNLOEXnxpCE5O+u2WKysVvPflASrlSjq382bGJP0DGH/de+WBI9sXL43ByU47C6RWC7y7/hj34tKxNDXmu+fG4aDDpjo5p4Cnf9xJTnEZ/q4OesVOeHoWczfuJr+snGaOdvw6YwLOVtq9PUq1mi/OXeDXGzcB6OrpwbejRuBgrrtMS6VWs+X+Pb68epGCSk3fwjj/FrzRrQ9O5rotuHVd82xqLMeSojibFkd2eU1L36ZWdrS0cybAxpEAW0cCbRxxt7BG2ggXt1KFnJDcDG7npHE7O5Vb2ankVJRxLTOZa5nJfHDjFKO8WzDNry2t7V3qnUVs6eDE/gnT+eTKWdaF3Ob9S6cpVypY1EF/RlAikbBsQD9icnO5npLKy4eOsHXaFL0ZtKVD+nA+Jp6k/EJ+u3KLBX266Iyb1K01P5+6RmZhCadCYhjaTrfj3pgeGsFzOTyBwtIKrM11C5SgTs3YfuIOV0ISUKsFnZlIAEd7SzzdbElOyyc0Io3uddjR+/u7cOVyDLENMCHw8NLMzklLya/3moexddR81wrzSh9byZmxmREKuZLKcvkjP7eIiMh/F1HwiIj8y0mJyeTQb2cBmPf+JKSPuAk9PSmXnWuqzv/mqHqJlYdRKJSs/ETTWzRsXEda16MURqFQ8flnB1Gp1PQJCqRff/0uawDf/3aWuMQcbK3NeOul4Xo3hZfvxvPrXo1V9dLZA2nRVLdV9I8Hr3D8ZhQGUilfPjMKHxdt57SswhLm/bSLrKJSfJ3t9IqdW0lpPLN5L8WVlbR0deKX6eN1xmWXlLL44CGuJWsGj87v0oklvXthoOf3GZqdyRvnjhOSnQlAoJ0DH/QeSBe3+j2tTy4uYFvMPXbE3COz/A+nMzMDQ3q4eNHX3Zcgdx88LWzqdb76YG5oRDeXJnRz0Qy/FASBxOICjiRFsi36LgnF+WyJvsOW6Du0sHVimn87Jvm2xsSg7oylkUzGuz37Y2VkwsqbV/j86gXKFApe7tJTr3AylMn4asQwRqzbyN30DFZdCealXj11xlqYGPPqoN68uvsoay5eY3LHVtiZa2cQjAwMmNytDatPBLP54m29gqepqz3+Ho5EpWRz6nY043vp7iNq6++OqbEheYVlxCRn4+/lpPc9aBXoXiV4UusUPE2bas4TF1v/bI2rh+Z7kN6A+T0PY2WjEe6CIFBcUIaNff1EeUOozm5Xlus3mBARERH5M2LHn4jIv5y1H+5GpVTTZVBr2vXR7TL2V1jz8X4UciXte/rRc4j+5m597Nx4maS4bKxtzZlTz+zQpo0XiY/LxtralBcWD6419kJwNHuP3AHgrZeGY2ejOxuSllXIu6sPIwgwYUBbRvRuqTPuYHA4vxy5qjnfkwPpHOCpFVNUXsGCX/aQml+Ep701vzwzETsL7c3v5dhE5m7cRXFlJZ2auLN+5kTdGaDMLMZu3My15BTMjYxYNXokrwX10Sl2VGo139+6yrjdmwnJzsTSyIh3e/bn4KSn6hQ7lSolBxPuM/3EVnrv+ZFVIZfJLC/BztiU2c07sWngVG5PWcwv/ScyPaD9IxU7upBIJHhb2bKwVTdOj53P74OnMdq7BUZSGeH5Wbxz9TgD9//C8aSoes/cWdKlJ0u7aXrYVt0K5sPLZ2td62Zl9WBGz+rga1xPSdEbO6JVIC1cnSiTK/jpwnW9cZO7t8FAJuVOQjphyfoHjA7tpBFDR6/rd3UzNJDRsbnmM3jlXoLeOIBWVe5roRF1u69VC56EhGxUtdhoP4yru6bkLyOtALW6fmsexsBQhoW15vNflP94hoMam2oEj7xCFDwiIiL1RxQ8IiL/YkKvRHP50G2kUglz35vwyM9//VwEwac0RgUL3hnTYKOCtOQ8fv/lHADPLBmCVT1q6qMi0/l9s2bQ4+IXh2Brq991KyunmM9WaXqXpo3rTJf2ug0AKuQKlq48QFFpJS2buvDik0E6425Gp/DBJk0f0OwhnRnTQ1sUVSiUPL92H9HpOThYmvHT/PE4WGnf4+mIWJ75fR/lCiU9fb34efo4nbbT5+MTmLZlG5klJfja27FnxhMMDfDXeX9JRQVM2beNL65eQKFWM8THj9PT5jK7TQe9mSCAcqWCX8Kv0XPXap47v4+L6QlIgN6uPnzfZyzBE5/j3c4D6eXmjXEjDAQeBVKJhB4uXqzsM5qrE59jWecBuJpZklJSyPyzu5l5ajuxhbn1OteC9l14v1d/ANbeu8mb50+grkX0jAgMYHzLFqgFgZcPHaGoQretsVQq4aUBmgzQlut3SS8s1hnnYGXO0Laa3+Hmi3f0XndwleC5GZ1CVoH+eULd2ngDEBySoDcGNBkegPtR6bXOAgJwcbXBxMQQhUJFSj0zNo7OVkhlUhRyJXk59Zt/9Gesq77PhXmPR/AYmWgy0JUVYkmbiIhI/REFj4jIvxS1Ws2aZTsAGDqjN14Bbo/0/PJKJT99uA+AMTN7NdioQBAEVn16UGNj3aUp/YfVbWMtlyv5/LNDqNUCffs2J6hvc72xKpWaj785TFFxBQG+zjz9ZG+99/HF+tNEJmZhY2nK8hdGYaSj4Tw5u4BXfjqAUqVmUAc/nh2tXdqkVKl5ddMhbsWnYWlizI/zxuNpb6MVdzQsiue3HUChUjEosBmrp43G1Ei7LGvbvRDm7dpDqUJBtyae7HhiKk3ttMvnBEFg+/0Qhm1fz42MVCwMjfiy31B+HDK6VhvmaqHTe/ePfHTjNDkVpTibWvB86x6cH7eAjYOmMMI7sNbBpf8EtiamzGnemVNj5vFs6+4YSWWcT4tn6IFfWX7zDCWKyjrPMbN1Bz7vOwQJsCX8Hq+cPlKr6HlnQD88ra1JKyrm3ZOn9GaFevl60dnLA7lKxfdng/We78le7QE4cieSnCLdm3s3eyvaNnVFEOD4zSi95+rWRlMGei8qjdJaelO8POyxMDemolJBXGLtpWpSqQSfqtk6cfXs45EZyHCuspZOT21cH4+1XbXgaZxgqgsjEzHDI/LvoFwp/9v/iDQesYdHRORfyoV9N4m6nYCpuTEzXh/9yM+/b/0FUhNysHW05InnGj7E9MzREG4Gx2JoZMDzS0fUKzu0ccMl4uOzsbEx4/k6Stm27bvO7ZAkTE0MWfbySAwNdW/aD5wL5eD5MKQSCR89OwJne22TgrIKOUtW76ewtIJW3i68P1PbploQBD7cdYqzYXEYG8j4bs5oAtwctc51KiKWl3ceRiUIjG4TyCdjhmDwp+ZsQRD4+uJlfgjWlM6NbdGcT4YO1ik88srLeOPcCY7Fa4ZPdnZxZ8WAYXha2eh9byqUCjZH3WF1aDA5FZrNtoeFNc+37sF431YYSv9dAkcfZoZGvNo+iEm+bfjg+klOp8byU9hV9saF8VXPkfRy8651/eTmmv6fl04dYndUOM7mFrzeTbdlu6WxMStGDmPq79s4cD+S/r6+jGquXSIqkUhYMrAn037dxu47Yczt2QkfB213t1ZNXGjr5crdxHR2BN9j4WDdRhpDOgdyNy6do9cjmD5At7Ocp7Mt7k7WpGYVcvN+Mn06+OqMk0oltPB35drtBELup+LftPaHFE2bOnH/fhpxcdn0619r6ANcPGxJT80nPTmvXv14f8baTtO387gyPMZVGR5R8Ij80ww/sxxZI4ZzNxZVad0PgkT0IwoeEZF/ISqV+sGQ0YnPD8G2FgezxlCYV8rWH04DMPvV4Zhb6re41UVpcQVrvj4GwLQ5vfHw0j8os5qYmEy2bvmjlM3GRn/5W2xCNr9uvgTAC/MG4OmunRUBiE3O4csNmtfxzMSedG7ZRCtGEATe33ic2PRcHKzN+eqZUTpn7aw+Hszua6FIJRI+nz6Cjk21+2UuxSby4o5DD8TO8rFDtIZKKlQq3jp2gt1h4QA8170ri3v20CkI72VlsODYPtJKijGUSlnSpSfz23bWO6hSEAR2xYXy2a2zD9zWHpXQUQlq0suKSCzJJbE0n9SyAhRqFWpBeOiPGjUC9sbmNDG3o4mFLU3M7XAysWhwOeTDeFvZsnbAJE6lxPDB9ZMkFhcw89Q2Pu42lKl+bWtdO9ovEEEQWHzqEKtvX6Ozqzv9vXQLhvZubjzbvRsrL1/ho9NnCfLxxspE+7Pf3tONID8fzkXHsz74Fu+N1G2zPq1nO+4mprP3ejjPDOym00xjUAc/Pt92hvDETLILS3C01t3I36WVF3tO3+N2RIpewQM8EDzRsZl6Y6rx8tZ8L5OT6lcqCODsYgNATlbjhodaVn2viwvKGrW+LgyNNd9dRaXysZxfRETkv4koeERE/oVc2HeD5OgMLGzMGPtM/WbaNIQt35+krKQC3xbuDBirf56JPjb8eJr83BI8vOyZNLP2IYigEXBffn4YtVqgT1AgfYL0my8oFCo++fYwCqWKnl2aMXxAK51x5RUK3lx1kEqFiu5tvHlqpG677k2nbnHiVjQGMilfzBuJo432hnPPtVBWn9CUL701vj/9W2lvOG8mpvLc1v2aMrbmzfhkjLbYKZMrWLRvPxcTEpFJJHw4eCCT2+g2gtgVGcYb544jV6loamPHyoEjaOWo/4n9/fwsll09zvUsTdO9h4U1z7XuwfimrRpcsqYS1ITlp3M5K447eakkluaRXJqPopEDR01lhnia29LcxoX+rv70cvLFwrDhTz4HeDSjp4sXbwQfZU9cGEuvHCG5pIBX2vWpVVCN8W/O7aw01oXcZsmpIxya9BTulrofEizo1oVDEZHE5uXx7aUrvDOgn864uT07cS46nr13wlncvwe2ZtpmFANaN8PCxIi0/CJuxqfS2VdbJNtbmdPCy5nwxEwuhyXq7BsDaOfvzp7T97gblar3dQL4+mjMCGIS6nZf8/DQZKZSUuvvumZXZS3dWMFjVjUfqLREd5/UX0VmoPnONcZUQUTkUXK43xtYWT3ah5G1UVRUhAsr/rbr/dcQBY+IyL8MlUrN718eAmD8wkGYW2pvtP4KaQk5HNysmX8zd+mIBttcx0ams3/7NQAWvTYCIx3Zkj+zY/s1oqMzsLQ04fkXai+f27jjCtFxWVhZmvDKokF6N7pfbTxNQloeDjbmvPuMdokawPXIZL7dfQGAlycG0dZXuw/qanQSH+w8BcC8AV2Y3F27Fyk0LZNnft9LuUJJ72befDVhmFYZW3FlJfN27eVGaiqmhgZ8N3okfZtqWwcrVCo+rponAzDQy5cVA4ZjZaxbIBTLK/n67gXWR9xEJQiYGhiyuE1P5jTvXG+hIwgCiaV5XMqM40p2PFezEyhSaG9IDaUyPM1t8TK3w8PcBlOZIVKJBKlEgkwiRYIEiQSyyktIKs0jqTSf1NICylUKooqyiCrKYl/SPQylMno4+jDALYB+Lv44mWqXGerDxMCQFT1H4mlhw8p7l/g+5AopJYV83mN4rYYLb3QP4lZGGveyM3n+xEG2jdE9c8dIJuOdAf2YtWMXv9+5y8yO7WliY6MV19nLnRYuToRnZLHtRojOuTwmhgYMauPHnmthHLkdoVPwAPRs6U14YiaXwuL1Cp42/prPZkRCFhWVCp3DcgGaeWvKLBOSclCq1Fqfw4dxr7KZTkvNRxCEemXh7KsET26ObsOGuqjOFpcVPybBU/U7VSkbJ85FRB4VpgZGmBo0bIzDX0HxN17rv4goeERE/mVc3H+TpKh0LKzNGDNP99Pnv8Ivnx5EpVTTKSiQ9j38GrRWrVbz3aca04HeA1vSsZv+0ptqkpNzWb9OIzoWLBqAnZ3+2RwR0Rls3KHJtCxZMAh7W92xJ4IjOXA+DIkE3l84DFsr7fK4jLxilv5yCLUgMLJrcyYHaZdGJWTns2TDQZRqNcPaB/D80B5aMdFZOTy9cTcllXI6ebmzcvJIjAxq/tVZVFHB7J27uZuegaWxMWsnjqO9m7a4yikr5dkTB7iapsnSLO7UncWdeugc8ikIAvsT7vPxjdNkVc3RGdYkgHc6D8DNvH5PFbPKi9mXfI9dCXeIL6lZ1mRpaEw3Rx+6OHjha+mAl4U9rmZWyCQNE8BytYq0sgISinO5mpPAybRIkkrzOZcZw7nMGOAQHew9edqvB/1d/eu16ZZIJCxp1xtPC2veuHKUffHhpJcVs6bveGyMdT8AMJYZ8P3gUQzfsZFbmWl8cfUCb/boqzO2l7cXvby9uJiQyIoLl/hm1Aid9zCrewde23OUzdfuMKdHR4wMtAXU8PaB7LkWxvF70bwxth+GOmJ6tfLh58NXCb6fpFekuDpY4WhrQXZ+CWFxGQ+sqrXinG0wNTGkvEJBcmoePk30l5O6uFgjlUqorFSSk1OCo2PdwtOhqnw2L/uvCZ7SxyV4qjI8KqWY4REREak/ouAREfkXoVar+f0rTXZn3IKBmOvYyP8Vbl+O5srJMKQyKU8vHdng9ScO3OH+vWRMTI14ZsmQOuPVaoEVXx5BLlfSsZM3Q2qZ81MpV/LxN4dRqQX69wqkfy/dZW9pWYUsX6uxlp41uiudWmj37cgVSl77+SD5JeUEeDjy5hMDtTbahWUVPL92H0XllbRp4sIHkwdrxSTlFTBnw24Kyito7ebMj9PGaLmx5ZeXM2vHLsIys7AxMWHdpAm0ctEuTXu4X8fC0IgVA4Yz2KeZzteYU17K61cOcyolFgBvS1ve7zKIIPfah00CKNQqzmVEszPhDuczo1FVuZEZSqS0t/ekh1NTejj50NLGrVar6/piJJXhbWGPt4U9fV39ea3VIGKKszmVFsmp9Eju5adxKzeZRbnbaGHtwrPN+zDANaBewmdSsza4mlmx8NwermUmM/7IRtYNmEwTSxud8Z5WNnzRbygLju1jzd0bdHHzZKC3blH+Wp/eXEpI5GBEJHM7d6S1i/aQ2qEt/fny5AWyiks5EhbJmLbaA3I7+3rgYGlGTnEZl6MSCWqh/Ttq4eWMjbkJBaUV3ItLo4OfdiZIIpHQ1t+dk1cjuReVplfwSKUSfL0dCY1IIyY+q1bBY2Agw8XFmrS0AtJS8+sleB5keBopeMwes+CRVguees4WEhEREQHRllpE5F/F+b03SIxIw9zKlDHz62mrVE9UKjVrPt4PwMgnu+Pl1zAb6qLCMn5dqREaM57pi6OzdZ1rDh28w717yZiYGLLk5WG1bnJ/3XyRxJRc7GzMeOkZ3QNMlSo1y1YfprRcTutmrjw9Trcz1hc7zhKakIGVmTFf6jApUKrUvLLxEAnZ+bjYWPLtrNGY/MnKOrekjKc37ia7pBQ/J3vW6Jizk1dWzoxtOwjLzMLW1JSNUybpFDsn4mOYtHcraSXFNLW2Ze+EJ/WKnTOpsQw98CunUmIxkspY0q43R0fPrVPs5FaU8lXoKYKOfMOzwds5kxGFShBob+fBRx1GETzyVTb2mcnCwN60tfN4JGJHFxKJBD8rJxYE9mZHv6c5P+wlnvHviZmBEeGFGTwbvJ2xp9dwLiO6XsNGe7l5s3PodNzMrIgrymPi0U2klBTqjR/a1I/ZrTV9aS+fPkJqse5elBbOToxuobFF/+zcBZ0xRgYynuzSDoB1V27pvF+ZVMrQdpp5O4du6x4wKpNK6d7SG4BLYQl6771tVVlbXX08zar6eGLr0cdTXdZW3z4eOweN4MnPLWlU2ZiFlSYDV1pU3uC19UEsaRMREWkMouAREfmXoFKq2PipRpCMXzQIi3oM8WwIp/bcJCEyAwtrU558vuE21JvXnKWwoAwvXyfGTu1WZ3x+fim//HwWgDlzg3Cpcn/SRXhkGtv33wDg1WeHYG2lu2xp48HrhMSkY2FmzAeLhussDTpyLYJdF0KQSODjOcNxd9AWZisOXSA4OglTI0NWzRmjNVi0QqFk0db9JOUX4mFjxdoZE7Sa1qvFTkR2Dg5mZmyeOonmTto21tvvh/DMsX1UqpT0beLD3gnTaWZrrxVXoVLy3rUTzD61g5yKMgJsHNk/YiYvtOmJSS29K7kVpXwWcoL+x75lTdQlcitLcTA2Z65fdw4PWsTWvnOY5N2+USYCjwJnU0uWtBrA6SEvsCCgF+YGRkQUZjL/8hZmX9xEYkndG/EAW0f2DJ9BgI0jWeUlPHN2N+VK/bbEb3QPoq2TC4WVFbx57rheYbWkV08MZTKCk5K5lZqmM2ZKxzaYGBhwPyObkFTdzmjVgud8eDwKPRvxHi28AbgWkaT3vlv7aQRPWGx6rWKwaZUrYnxSjt6YatzcbABITyuoMxbAxs4ciUSCWi1Q2AinNfNqwfO4MjwysaRNRESk4YiCR0TkX8KpHVdJjcvCys6ccXoyHI1FXqlg07fHAZiysD9WtvqHWeoiOSGHAzuuA7Dg5aEY6JmJ8zBrfjpDSUkFfn4ujB3XUf+9KZR8+t1R1GqBwX1b0LOL7sxHZEIWP+/R2Fq/8lQ/3By1hUxSVgEf/34SgKeHdaVn1VP1hzlwM5yN528B8Mm0IVqzdtRqgaV7jnI3JR1rE2PWTB+Ho2XN96ta7ETm5OBobs7mqZPxd6hZWiQIAj/cusprZ4+hFgQmBbbil2HjdJoTRBVkM/bQetZF3ARgVmBH9o2YSaCtk873Av4QOgOOrWRt9BUqVEra2rrzfbfJnB32Iq+1HoSvZd124X8XtsZmvNSyP6eHLmaOX3cMpTKuZMcz4czPnEqLrHO9s5kla/tPxN7EjLC8TJZeOaJXFBjJZKzoPxwjmYxzyQkcitV9fndrK8ZUzeL59cZNnTE2ZiYMbK75TO69G64zprWnC3YWZpRWyrmdoFs4dfBzByAyOZvySt1izdfDHplMSlFpJRm5+kvKPN2qsjZpdQ8HdazqycmpZ4maTCbFwkpTllZU2PAsjXHVYNDKisc0JLHqd/4XXNBFRET+HyIKHhGRfwEKuZLNX2jm7kx+YdiDOvhHxYGNl8lOL8DBxZrRM3o2eP3P3xxDpVLTtbc/HbrWbVQQEpLM8WOaLMviFwcjq8VJauP2YBKSc7G1NuP5ubrL+CrlSt7/6QgqlZp+nf0Y2qO5VoxcoWTpL4coq1TQ0c+D+SO0s1BhKZm8v0MjiOYP7MrA1tqmDV+fvsTR8GgMpVJWThlFU4eaM4BK5HLm7tr9kNiZhK99zRi1IPDh5bN8flVTKrWwfRc+7ztEZxnZ71F3GHVoPREF2dibmPFb/0m812WQ3qxOkbyCzx8SOuUqBW1s3fi5xxNs6zuHgW6B/+rBozZGprzeehBHBi2ivZ0HxYpKFgVv4+uw06iE2p/au1tYs6rPGGQSCfviw/n1/nW9sb62djzboSsAnwafp0Kpe27LnM4aMX48KprE/AKdMePaaXp3DoVEINdxHqlUQq9AbwDO34/XeQ5XOytcbC1RqtWEJmTojDEyNKCpuyb7F5WQpfuFAR5uGrvptMxClHX0sjhWlahlN8B1zaoqu1xc2PAMj4mZxkmqsvzxDgb9K3OfRERE/v8hCh4RkX8Bx3+/RGZSLrZOVoycE/RIz11aXM62HzXDOacvHoyRHrtbfdy4HMPVC1HIZFKeXjy4znilUsW3VUNJhw9vR/MW7npjY+Kz2LTrKgAvPTNQbynbml2XiU3JxdbKjNdnDdC52flu3yUikrOwMTfho9lDtWbk5JWU8eK6A1QqVQQ19+HZwdr9PztuhvDzRc0m+sPRg+jqU7NxvFKpZOGefYRkZGJrasqmKZNoaldT7MhVKl46dZi19zQZg3d69OP1btpzZBRqFW8HH+PN4KNUqpQEuTXlyKg59PPQLSgFQWB/UgjDTnzPrw8JnTU9prG971z6uDRr1CZQEAQK5WXEFmdwJTuKAyk3+TX2NF+GH2BlxBF+jjnF5vgL7E66ytG0O5zLDCeuJBN1HeKkLjzNbdnQZyYzfDV2zz9GXmTepd/Jq6x9k93dxYu3O2lmU31y8wwX0xL0xs5v2xkXcwtSiotYF3JLZ4y/gwNBPt4IwG83dWd5uvl44mRpTmFFJRdiEnXG9K4SPBf0CB7ggS36nVj9PTr+XpqsXlSSfsHjaG+JkaEMlUpNZpb+fiYAR0dNhic7u/5zdaysNd/DooLGZ3gqyh9PhqcebV8iIiIiWogubSIi/zDyCgVbVhwGYMqLwzAxe7S9FjvWnKW4oAxPXycG1lJapgulQsWPXx0BYMzUrjTx0e5R+TO7dl4nPj4ba2tTnp7fV/+5VWo+++4oKpWaPt396NszQGfcnchUNh/R9Pe8OXeQTgvq8yFxbD6l2dC+N3MIzrY13ahUajWvbz5CRkEx3o62LH9imNbcnkuxibx3UDOPZ1FQV8a2q+nIpVSreengYa4kJWNuaMhvE8drZXbKFQqeObaP88kJGEilfNlvKGP9tZ298irKWHRuL8GZSUiAV9r3YWGr7jrtqQFii3P44M5hgrMTAGhq6cDS1oPo49xwkVOiqOBuQSK38+K5k59AZFE6leqGP403NzCmpbUnrWw8q/7rga2RfstxXRhJZbzddijt7Dx4+9YBLmXFMf70GlZ2nUQbO/1CeVZgR0LzMtgVG8pz5/dyYMQsPHU4t5kaGvJq1968fPoI398KZlJgK+xNtT8/T3fuxLn4BHaGhLG4Zw9sTWsKb5lUyvBWAay7couDIREMCNQWpT0CvJBJJcRl5ZGSW4iHvXbJZTtfN47diOR2jO6yNwB/L0cOXYDIRP2GBFKpBDcXGxKSc0lJL8Dd1VZvbLUzW052cb1n8VhWZXiKGpPhMf0jw1Pf6zUE4UFJm5jhERERqT+i4BER+Yc5vOE8OWn5OLjZMvypPo/03HlZRez9TVNWNeuVYch0zAipjf3br5KckIO1rTlPzqs785SZWciG9RcBmL+gP1Z6MjYA2/ZeJzI2E0sLE72ubGUVcj5YcxRBgJF9WtKng/ZGM6ughPfWazJKT/RvT5/W2m5mq48Ha0wKDA34euZILE1risrorBwWbz+IShAY3SaQ5/vWzP4IgsDbx09wPDoGI5mMH8eP0XJjK1comHtkD5dTkzA1MGD1kDH0beKjdS+R+dk8fWYnySWFmBsY8W3vUQz01D0PqUKlYHXEBX6NuoxCUGMsNWBRYG/m+PfAqJ5la0q1iuu5sVzOieROfiJRRekIaD8mtzI0xcnYGkcTKxyMLbE3tkCpVlOmqqRcJadMKadcJadYUU58aRalykqu5cZwLTfmwTmaWbgwxrMTI907Ym5Qf+E+0rMV/lZOPH91BwkluTxxfh0fdRjF2CbaQ2BBs9n9uNtQogtyuJebwfyzu9k1dDpmhtqD+cb5t+C3e7cIzcnk2xuX+aC39metWxNPWjg5EZ6Vxe937vJsd+1yyBFVgudMZBwllXIsjGtey8rUhHbebtyMS+VCRDzTerbTOkf7ZhoRFxKfjkqt1spCAgRUZ3gS9Wd4QFPWlpCcS0paPl07aH/OqnGoEjyVlUqKiytq/U4+eC3VGZ5GCB7jKsEjCALySuWDjM8jR9Q7IiIiDUAUPCIi/yAKuZIdKzWb9WlLhmP0iDcHW1efprJCQWC7JnQfqHvCuz6KCsvY/PM5AOY8NwALy7o3Sj+tPk1FhYI2bTxrnbmTllHAb1svA/Dc3H56B4yu3nGJ1KxCXOwteenJvlrH1WqBZeuOUlBaQaCnEy+M7aUVcyUqkTWnNGVzyyYNpJlLzUb+grIKFv6+TzNYtIk7H40epPX0eMXFS+wMCUMqkfDtqBF0b1Jz9k+FUsn8o3u5nJqEuaEh60dMpJOrdobiVEoML5zfT6lSjpelDT/3m4C/je6s2bXsBN68dYDkUk1jepBzM95pNwxPc/1P8x8mviSLg6m3OJJ2m5zKmv0bnmb2tLP1pr2tN61tmuBiaoOxrP6fPaVaRVxJJiEFyYQVJhNakExCaTYxJRl8df8gP0afYJR7J6Z4dcfdzK7uEwL+1k7s6vc0S2/u40RaBG/c2IetkSlBLrrFoInMgB/7jmf0oXXcz8/i01tn+aCrdsmlVCLhrR5BTNu/nd/D7/FMuy64W9Yc3CqRSHi6c0eWHDrC5tt3eaZrF61+q1ZuznjZ2ZCYV8D56HiGt9LOSPYO9OFmXCqXIxN1Ch5fN3vMTYworZATm5aLv4f2796vieZnmbnFFJVWYGWuu5/Poyqrk5pRoPN4NUZGBlhbm1JYWE52dnH9BI9NVQ9PI6ylHxY4leXyRy94xJo2ERGRRiAKHhGRf5Azu66Rm1GAvYsNg59ouJlAbWSnF3BkazAAM+uYgaOLrWsvUFJcgY+fM4NGta8z/t7dJM6di0AqlfDcC9pDPKsRBIFv1pzSDCNt04Sh/XQLsbtRqew4cRuAN+cOxkJHqd/Ws7e5FpmMiZEBy+cOx+hPs3Ryikt5c4smQzShaytGdqhpdqBSq3l19xFSCorwsLHiu6mjMDKoeY5Nt++wOvgaAB8NHsggv5oucnKVikXH93MhJREzA/1i55fwa3x84zQC0N2lCT/0GYetifbmU6lW80PEeX6IOI8AOJtY8nbboQxyC6zzd1ikKOdE+j0Opt4krDDlwc+tDc0Y4NKKjnZNaW/rjYOJVS1nqRsDqQx/Kzf8rdyYgMYYoFBexomMe2xPvEJCaTZbEy+xLfEyfZya84R3T9rb6c9CVGNhaMx3XSfx5s397E66y4tXd7I5aBYtbFx1xruZW/F1r1HMOLmNDZG3GOPTgo5O2kM9u7s3oYd7Ey6nJrH23k3e6dlPK2ZogD8fnj5DVmkpFxMS6Nu0ZqZQIpEwINCXtZdvck6P4Onsq7n2nYQ01GpBq2xSJpUS4OnIrehUolKydQoeCzNjHG3Nyc4vJTkjn5a+ul+7c3VvTj3MCGxszCksLK93xsa0ynigvLThfTgygz+E4uMYDqqssv02aGC2WkRE5P83ommBiMg/hFqtZtf3GqvosfP7Y2j0aJ8/bFt9GqVCRavOTWnbrW5ntYfJSMtn/zZNVmTuC4NqdVkDzcbm++817mcjRrbD11e/nfLFqzEE34zDwEDKS89oZ1NA48r2ya8nEAQY1aclXVt7acXEpeeyco+mfG7JhD54OdfMfKjVAm9vPUZOcRnNnO15fUxfrXN8fzaYCzEJmBgYsGrqaK1ZOyeiY3j/pMbwYXHP7kxuUzNrpVCpeP7EQU4nxmFiYMDaEeO1xI4gCHx26ywfVYmdaX5t2TBwik6xk1FWxKyLG/i+SuyMb9KWw4MWMdi9ea1iJ6+yhJWRRxh59lM+C99HWGEKMomUPk7N+az9kxzut5SlLccyyLXNXxY7+rA2MmNik25s7bWYbzvOoruDPwIC57LCeebaz7x/byfFirozBhKJhPc7jKS7ow9lKgXzL28hvUx/Y35vNx+mNNOUvr1//SRqPRmAZ9p1BmBL+D0KK7VnxBjJZIypGkS6MyRM5zmC/DSi7UJ0Amq19nWauzthYmhAQVkFCdm65wsFeGi+GxHJ+kvWPF00n+WkDP220472mqxodi321dVYV5WoFdbTZvqB4GmE8YBEInkgeh7HrBylQiN4ZPWwxhcRERGpRhQ8IiL/ENdPhpIYkYaZhQnDZz3a3p20xByObtcIlhkv6s+26GPD6tMoFCradfahU3fdc3Ee5tjREGKiMzE3N2bWbP2vpbxCzrc/a4wBpo3rQhMP3eVOa/cFk5CWh721OS88od07pFCpePu3o8iVKnq29GZCb+1ejw3nb3IpMhFjAxlfzBiOqVHN0prTEbH8cF7zHn0waiCBLjWftodmZrLk0GEEYGqb1jz3p74OlVrNS6cPcyw+GiOZjJ+HjqWbW01XN7Ug8PbV46wO1WTalnboyyfdhuq0jT6VFsmY0z9xPScJMwMjvug0juWdxtQ6MDSvsoSVEUcYe/4LNsVfoEKloKmFE4sDhnOw7+t82WEG/ZxbYij9+5L5UomU7o7+fNtpFtt6vchYj85IkHAo7RbTLq0kOCe6znMYSWWs7DoJPytHsitKmH95CyWKSr3xr7QPwtLQmHu5GeyMuaczpo+nN4H2jpQpFWwKvaMzZnxLTbbxdGwcxZXa1+vQxA1zIyPyysoJTdMeQmpoIKN1ExcAbsXrNiYI8NR8zqJS9JsSNKmP4Km2m66X4NGUqBXWM8NTbTxQUdY4p7XqBySPI8Ojqs7wiIJHRESkAYiCR0TkH2LnKk12Z9jMPpjrcB77K2z89jgqpZpOfQJoU4+5OQ8TG5nO6SMhADy9uG6xVFpaya+/ngXgqZm9sLHR/1rWbb1MVk4xLk7WzJik3RgOmmbtjQc11tCvzeqvs4dh7ZFrRCRnYWVmzLIZ2lmikKQMvj18CYDXx/bV6tuJz8nntT1HAZjepR2j29YsdcssKeGZ3fsoVyjp7e3Fe4NqWmGrBYFXzxzlYEwkhlIpqwePprend41zKNQqXrp4gM1Rt5EAy7sNZUGrblr3Klcp+ejuURYFb6NAXk5LG1f29p/P6Cb6e6BqCJ0EjdBpbuXOig5PsaXnYp706YW9saXe9X8XPhZOvNlqHGu6zsfDzI6sikJeuPEbn4btpUypX8AAWBmZ8FOPaTgaWxBVlMXiqztQqFU6Yx1NzXmhTQ8APr99jmK59rklEgkLqrI8v4XcokKp7UzX3MkRX3s75CoVJ6JjtI4bymT09NX0b52L1m0/3d5Hk+HTN4A0wOMPwaNvcOoDwZNeoPM4aKypAXLzS+ucxWPVwAyPmblGZJc3VvBUlZtVi5NHiVJeLXjEinwREZH6IwoeEZF/gMhbCYRcjsLAUMbYZwY80nPHhqdydr+m92Xmy8MavP7XlScQBIG+Q1rh19ytzvjNmy5TkF+Gh6cdY8bqt72OS8xm+37NnJMX5w/ARMc8IKVSxUc/H0elFhjQxZ++nbQb1sMTM/n1iKan5o2pA3C0rml4UFxeyaubDqFUqxncxo+JXWsKh9JKOS9sO0BJpZyOTdx4bXDNjFS5QsGCPfvILCnB196OlaNH1mhgFwSB9y+eZndUODKJhO8GjWSAd01RWaFSsvDsHvbFh2MgkbKy9xim+bfTei1Z5cU8cX4dG2M1r2d2s25s7TsHLwvdmS+lWsX6uHM1hE4Law++7jiTdd0X0cup7j6ff4K2tl5s7vECk5poRO7u5Gs8eek7bufpn1kD4G5mw489pmIqM+RiVhzv3zmsVyTMDOxEUys7cirK+O7eJZ0xI3wDcLe0Iqe8jF2R4VrHJRIJowIDAdh/P0LnOYL8Nb095/UIng4+mu/M7Xjds3aautpjIJNSVFZJRr7u7Ey14EmuJcNja22GTCZFrRbILyjVGwd/ZHjq3cNj2viSNuBvKWkTMzwiIiINQRQ8IiL/AFu/PgRA3wldcHSrn+tWfdn4jSZz1GdEW5q11D/LRBd3rsVxMzgWAwMZsxbVLcTS0wvYvUuTjVm4cACGejYhgiDw9U8nUanU9O7ajB6ddWedthy7RWRiFlbmxrz8lHZjuUKp4r0Nx1Cq1Qzq6M+QztqN45/uPUNqXhHutla8O2lgDQEgCALvHjxFdHYujhbmfD1pBEYPNT8LgsBbx05UDRY1Yc24sVga1ywpW3PnOutDNVmbFQOGM7Spf43jZQo5c0/t4GRKDMYyA9b0G88on5oZJICIwkwmn/2VkPw0bIxMWdNjGkvbDNZrN30vP4kZl1fxfdSxB0Lnm44z+a3bQno6BvwloSMIAnK1ggJ5MWnl2cQUJxNaGEtqWRbyRszo0YWpgRGvthjNqs5zcDaxJrU8j4XXfuFAiu5hn9W0snVjRZfxSJGwI+E2v8fd0BlnJJPxTtVA0t8ibpBaot33YyiT8XSbTgD8eveGTvE0srnmM3U5MYm8Mu2MSJ9m3gCEpGWSV6otINp6uSKVSEjOLSSnWFuIGBrI8HHRCNqoZN1lbU1c/yhp0yfwZDIp9rbmQN3GBdU9PAX1LWl7YFpQexZOH4+zpE00LRAREWkMYk5YRORvJj48hStH7iKRSJiyeOgjPXdMWCpXT4cjkUiYsVjborc2BEFg3WpNg/6w8R1x1dNf8zC//nIWhUJFh47edK3FGOHs5SjuhqVgZGTA80/31xmTkVPEL7uvAPDCE0HYW5trxaw/foOYtFxsLExZOlX7PKdCYth/8z5SiYRPnxyGlWnNcrgdt0I5GBKBTCLhm0kjcLKsmR369cZN9t/XHP9u9Ci8bG1qHD8cG8ny4PMAvNWjL2P8agqZUoWc2ae2cy0rBXMDI37tP5FuLjUtrAEuZMaw+OpOSpVyfCzsWdNjGk30ZHVKFBX8EH2MXUnXEBCwMTRjceBwhru1b7DIEQSB7Mp8IosTiSpOJLIokeTyDMqUFSgF/eVHtkZWOBnb4mxij5OJHc2tfOhgG4iRtOGWw13sm7Gl52K+uL+fI2l3+Dh0NyYyQwa56p65A9DfNYBXWw/ks5ATfB56gr6ufrib2WjF9fPwpbtLE65kJPFz+DXe6zJIK2Zy81Z8cfUCcYX5XE9PpYtbTVc3b1tbAh0diMjO4WJCAqNb1PwdO1qa08zRjpjsPG4np2sNIbUwMcbL0Zb4rDwi07JxCND+HDd1tSc6NYfELN0ZHBd7jbFEeaWC4rJKvdbUdjbmZOUUU1CHfbR5VYlaWT1d14yqDFSUf7Ek7XHkGhWVGgFu+Ljm+4iIiPwnEQWPiMjfzLZvNL0jPUe1x9NPt+VsY9n6g8YpLWhkWzya6ndK08XVC1Hcv5eMkbEB0+bUbaJwPzyVM6fvI5HA/Gf66d18V1Yq+OG3swA8Mb4LLk7aE+gBVmw6Q4VcSbsAd0b21raqjs/I4+cjGpOB1yb3xdaipstZbnEZH+zUvP7Z/TrRzrtmOV5UZg4fHzkDwEsDetLRq2b261JCIp+f0wxpfat/X7o1qWlAcCsjjZdOHQFgZqv2zG1Ts3yvQqVk3pldXMtKwdLQmPUDJ9PBUTvDtjXuJh/cPYxKEOji4MWqbpOxNtJ2bBMEgTOZYXx5/8CDOToj3TvwQsAwbIy0N9H6yJcXcSH7NncKIoksSqRAoT8bIEGCqcwYM5kJRlJD8uSFVKjl5MuLyJcXEVmc+CDWVGZMV/vW9HJoR0e75g0SPxaGJrzXehLGUkP2plxn2b3tmMiM6O0UqHfN7GbdOJ0eyfWcJD65e4zvu0/RGbeoVXeuZCSxNfouz7fpib1JzZ4yc0MjRjYLYHtEKDsjQ7UED0AfHx8isnM4F68teADae7oRk53HraRULcED4O/q8EDw9Azw1jrexMkGQK/gMTYywMbSlILicjJzi/UKnvpmbsyqMjZl9SxRqy4XUygaJ3geZKUeQ3lltZFCtbGCiIiISH0QBY+IyN9IWlwW5/dqSsCmvjj8kZ47ISqDS8dCNede2LC+IJVKzW+rNGJhzNSu2DvW3vAuCAKrf9C4rQ0e0ho/Pxe9sVv3XiczuwgnB0ueGN9FZ8zF23GcuxmLTCbl9VkDtMSTWi3w4aYTKJQqerXyYUinmqVsgiDw/s6T5JWW4+/qwKLBNQ0RKhRKXt51mEqlij7NvJnTo1ON48kFhSw+cAi1IDC+ZQtmtG9X43hSUQHzjuyhUqVkgFdTlvWsKfAUahXPn9/H5YxEzA2M2DBwCu0dawoutSDwZehJfo3WZLHGNmnDhx1G6SxhK1VWsjxsD8fTNY5jnmb2LG05ls729TOgKFdVciXnHmeyrnMnPwo1f5QWySRSvM3dCLD0xt/SC18LD6wMzTCTmWAiM0YqqdmvVKwsI7Mil6zKfLIqckkrz+Zabhg58gLOZt3gbNYNTGXGdLFrxQDnLnSwrV8fkUQi4fWWYyhXyTmWfpc37vzO1x1n6n2NEomEZW2HM/b0T5xMj+RcRrTOoaS9XL1pbe9CSG4G6+7f4OX22uJ9fEBLtkeEciQumg/7DMRYVvOfwr5NfVhz7Trn4xNQCwLSP72eDk3c2HErlFvJeowJ3Bw5djeKyLQcncebOFX16GQV6DwO4GRnQUFxOVl5xQ+Gkf4Zm6phwAVFtQuehtpMV5eLKRsteDT//fMcokdBZdVrMBYFj4iISAP4nxI858+f54svvuDmzZukp6ezZ88exo4d+0/flohIvdm+8ihqtUDnga1o1ka71OmvsLVKgPQc0hovf/0CRBenj9wjITYLC0sTpszqXWf8+XMRhIWlYmJiyOw52rbR1WRmF7FppyYrs3BWX51GBRWVCr7coCmle2JoB5p6OGjF7L54jzuxaZgaG/LGtP5aG+r9N8I5ExaLgUzKJ9OGag0P/fz4eaKzcnEwN2P52CE1NmIVCgWL9u2noKKC1i7OfDi4Zt9PQUU5sw7tJreinJYOTqwcNBLZQyYGakHgtcuHOZEcjZFUxs/9J2iJHblKySs39nAs9T4ALzTvy6LA3jqFQVRROm/c+Z3kslxkEilP+fRhtm8/TGS1Z1AEQeB2fgQnM68RnBtCpfqPza2/pRe9HNrR3MoHXwsPjGX12yxKJBKsDM2xMjTHz/KPz+vCZmoiixO5mH2bSzl3ya7M51z2Tc5l36SdTQBPNx2Lj0Xd/WMyiZR3W0+kXCXnfNZ9Xrm1ke86zaGNre7vhr+1EzObdWNt9BU+vHuUro7eWu+LRCJhUatuLDy3l/WRN5nfsiuWRjX7sLq4euBibkFGaQlnk+IZ4lNTOLV3c8XCyIj88nJCMjJo61ozE9vBU/PaQtOyqFQoMf6TY1iAq+YzHJWuu0enemZUYqZ+UwInW0uiErPJyivRG1NtRlBQh/vaAxOCerquVWd4Gi14qmYUPQ7/jGrBY2QqlrSJiIjUn/8p04LS0lLatm3LqlWr/ulbERFpMNlp+Zzcpnm6P/WlR5vdSYnL4vyhuwBMe7Zh2R25XMnGHzWlXpNn9cLSSru86s/xP685q4mf0hXHWrJBP204T6VcSZsW7vTvpW0wAPDb/quk5xThbG/J3LHdtY5nFZTwbdWA0efH9MTVrubgzPT8Ij7dp7mfZwd3J8Ct5tPw05Gx/H5d894sHzcEe4uaJU4fnj7L/axs7MxM+X7MaIwfEkuVKiXPHNtHXEEeruaWrB0+HnPDP8SCIAi8e+0Ee+LCMJBI+SFoLD1cag5JrVApeDZ4O8dS72MolfFFp3E827yPltgRBIE9ydeYE7ya5LJcnEys+anLPBb6D65V7AiCwNXcEF66/RXvhK7mXPZNKtVy3EwdedJrGGs6v83X7V9mgucAWlg3rbfYqQ2pREpzKx/m+Y5nbZd3+ardS4xy64OBRMadgkheuPU5K6O2ki8vqvNcBlIZH7edShf7ZpSr5Lx4cx1RRbozJwDPNQ/C2cSS5NJ8fo7U7cY2pEkATa3sKJJXsiX6jo77lzCqWZUbW7S2G5uhTEZPb83v8WycthtbEztr7M3NUKhUhKVrz+Pxr/oMJmTlI1cqtdc72gCQXVhKWYVuEeJcZTudmae/BNGmys6+rgyPWZXgKaun4Kk2H1E20mWtuqRN8hgyPPIKMcMjIiLScP6nBM+wYcP46KOPGD9+/D99KyIiDWb3DydQKlS07uFPy651D/NsCNt+PI0gCHQb0ALfFg1zZjuy+waZ6QXYO1oyZkrXOuP37b1FenoB9vYWTK4lPjQilZPnNT0+zz+tXaYGkJSez6ZDGtetl6f3w1RHI/JnW09TWiGntY8rk4La1jgmCALLtp+gpEJOWy9XZvWtWaqWXVzKW/tOADCrewd6VzlsPXgt4ffZdi8ECfD1iOG4Wf0h3gRB4J3zJ7maloKFoRFrR4zH2bymycGKOxfYGHkLCfBVr5EM9KyZKahQKVh0ZRvnM2MwkRnwU/epOufrlCvlvHtvB8vD9iJXK+npGMCmHs/TxtZLK/bh+7uWG8qLt7/kg7CfiS5JwlhqxEi3Pqxo9zJrOr3NE17DcDdtWC9XQ5FKpARa+bCg2UR+6vQ2vRzaoUbgWMZl5l//iCPpl/Q6jVVjLDPki/bTaWvjRYmygudv/EZ6ue7sh7mBEW+0GQLAmqhLpJYV6LgnCQtaacoafwm/rnN+z2g/jeA5mRBLqUJbCPRt6gPA+fgErWMSiYQOnpos3q0kbXHmbG2BtZkJSrWa2Mw8reNW5ibYVPWgJWdr3z9oStqAWjM8NlbVPTx1ZHgaWtL2oIdHW6zVB3V1hucR2xYIgkBluca0wNhEFDwiIiL1539K8DSUyspKioqKavwREfknKCuu4NgmTZZi8gtDHum5s9MKOFM1d2dqPaykH0ZeqWDbOs19PTkvqM5G4PJyOVt+vwzArNl9HpTK/BlBEFi97hwAwwa0JsDXWWfcyi3nUKrU9GjrQ5+O2r0b50PiOHM3FgOplHeeHFijlAxg7/UwgqOTMDE04OOpQzCQ1ew/WXbgJPll5QQ6O7JkQM8aaxPzC1h2XNO39FyPbg+e6Fez9X4I2yNCkUokrBo8iub2NTNH6yNu8l2I5r34sOsQxvi0qHG8WuxcyorDTGbIzz2eoKez9mtMLMlmdvAPHE2/g0wi5Tn/oXzVYQY2RroHuAqCwI28cJbc+Yr3w9YQU5KMidSIiZ4D+a3LuyxsNpEAK69/ZB6Pi6k9b7SYwxdtX8TPogllqgpWRW/jrZDvKVTo37iDxrb6644z8bd0JV9eyrJ721ELujMMQ92b09XRG7laxS9Rl3XGjPVpiaOpOVnlJZxOidU63srBGU9LaypVSq6kJmsd7+mlKasLzcikTK5tzd3aXfOZvp+hXbYmkUjwdda47iXoMSZwr3JiS9eTwbGrcinMryV7Y2GhKdUrKa3QGwNgUvUgQS6vn4Cp/uzUoVP1Uj1wVPaIZ+VUPGSTbWphXEukiIiISE3+04Jn+fLlWFtbP/jj6elZ9yIRkcfAye1XKCupwN3XmY79tR3I/gp7119ApVTTpqsvAW0b1hd0bN9tcrOLcXS2ZtCo9nXG7951g8LCctzdbRkyVDtTUc3FqzGE3E/F2MiAp5/opTPmakgiF27HIZNJefHJIK0NerlcwefbNKV2Tw7sQDP3mr092UUlfLFfYxH97JDueDnWnGe05044Z6LiMJTJ+Gx8zb4ehUrFkkOHKVUo6OzhznPda5oc3MvK4N0Lmp6oV7r0om8TnxrHjyZG8t41TeZoSbveTA+o+d5piZ2eT9LF0VvrPbidF8+c4NXElWRhb2zJ953n8lTTPjWMA2q85op8Pgj7mXdDfySqWJPRmeAxgLVd3mW2z2isjWo3m/i7aGHdlK/aL+HppuMwlhpytyCKpXdXklupPRvnYSwMTfis/ZOYyoy4m5/I3uTrOuMkEgnPBWrMCHYm3CazXFs0GMlkjPPRfNf2x+seMlr9ez2XpF225mppibOFOSpBICQzQ+u4v3NVn06WbmMCT3sbAJJyC3Qed7KpyuAU6BaC1hYaZ7bCYv3ZmwelanVkbqpNCNRq4bHMxnkYQRBQyDWCx8j40bYJlxVrhJ1UJhVL2kRERBrEf1rwvPHGGxQWFj74k5ys/RRPRORxo1arOfCLZuM+Zl4/pNJH97UrzCvl8JZgACbM028eoAu5XMnWdRob5imzej2YvaGPkpIKtm/TGBDMnNX7wXDBP6NUqvhxvSa7M3l0JxzsLbRjVGq+2XwWgEkD2+Hlqj2D5rej10nLLcLF1pL5w7tpHV++5wzFFZW09HBmeu8ONY6lFRTxyVHN+V/o150A55pi6ZtLl7mbnoGVsTFfjRhWI3OUV17GwmP7kKtVDPJuxsL2NZ3lQnMzePHiAQRgRkAHnm/do8ZxXWKnk4O2ED2dEcrzN36jWFlBa5smbOzxHB3sfLTiANSCmoNp51l48xOu5YViIJExzr0fa7u8y5ymY/41QudhZBIp4zz68U37V7A3siapLIPX7n5DRnlurevczexY6KeZn/Nd1FGyK3Rn5js7eNHR3hO5WsVvVc53f2Z0VdbtZEoMxXLtIZpBVYLnbFK8VtmdRCKhvZumbO12WrrWWn8nzWcqPicfuY55NU0cbABIzinQeW+OdQoeTblaYUndgqe8ovbhsA8PBP6rs3XqQqlQPXgvDev4O6WhlFW9F2aWJv9IBlNE5GHKlPK//Y9I4/mfcmlrKMbGxhgbi2lvkX+W2+fukxydgZmFCQOn9Kh7QQPYu+4CFWVyfFu40zlI/wwTXZw8eIeczCLsHS0ZMqbu7M7OHdcoKanAy8uBvv20Z5NUs+/YXZLT8rG1NuPJCbp7fPadCSEuNRcrCxPmjtMWMwkZeaw/oenteXVyX0z/5O52OjSWEyExyKQS3p88qEYpm1ot8Pb+E5RUymnr4cqcHjXn5VxJTGLNVU3m4JMhg3Cz+sMEQaVWs/jUYVJLivG2tuGr/sNqbKwyy4p5+swuKlRKgtya8m7nmo5ulSplvcTOtsTLrLh/CAGBIKcWfNh2il5jgsTSdFZGbyGiKAGAQCtvXvCbhpf5X5vhVK4qJ708lTx5HhIkSCUSpBIZUqRIJVIMpIa4mbhjafjXxFQTc1c+b/sib4WsIqMil9fufsPHbZ7D00x3mSPAJK/uHEu/S1hhCl/c38/n7adrxUgkEhYG9ubpS7+zNf4m8wN6Ymdccz5RSztnmlrZEVeUx4nkaMb7tqpxvLu7J4ZSKcnFhSQUFuBjUzNL2N7NjaNR0ToFj6u1JZbGxhRXVhKfk0eAS82Sx+oMT3IdGZ5sPYKn2nK6sER/uVp9MzwPP5xQKFQY63BLrEFja9kAxUNlc49c8FRleMwsazdWERH5O+h1eAUyM90zsh4HqrLaS1dFauc/LXhERP4N7P9Zk90ZOK0HZpaP7i/HkqJy9m/QuFRNe1a3KYA+lAoVW9dqsjuTZ/bCqI4NUGFhGbt2akTCrNn6szslpZWs26LpqZgzreeDgYcPU1xawU+7NPc9f3wPraGKgiDw2bYzD2bu9G1bs++lpKKSj/dobKxn9e2k5cq27eY9LsclYWJgwGfjhtTM3pSV8/KhIwjA1DatGRrgX2PttzcucyE5ARMDA34cMgarhx6YlCsVzDuzi4yyYppZ2/Ndn9EYPHRulaDm5eu7axU7akHNqqhjbIrXvPcTm3Tl5eajkOkoYVOoFWxLOsGO5BMoBRWmMmNm+YxiuGsvvSVv+sisyCCmJIq08lTNn4pU8uXazfS6cDJ2xteiGU3Nm9HUohnuph4Nvr6LqT2ft32Rt0O+f5Dp+aj1InwtdJcZyyRS3mw1jqcuf8/ZzHDOZITSz6WVVlwvJ19a2rgSVpDO+pirvNSyf43jEomEMT4t+PruRfbFh2sJHnNDIzq7enA5NYlzyfE6BI9GVN5KTUMQhBrfMYlEgr+zPTeT0ojKytESPE0cNAN2k3N1l/HVt6StuKwSpUpdQ9RX8yDDU8+SNmiY81pjkijyyocFz6Pt4Skt/iPDIyIiItIQ/qcET0lJCTExMQ/+f3x8PHfu3MHOzo4mTR7tTBMRkUdBWnwW106EADB6br9Heu596y9SVlKBt78L3Qc1rC/o1OG7ZKYXYGtvwbBxHeuM377tKmVlcpo1c6ZXb9320gCbdgZTWFxOEw87RgxuozNm7b6rFJZU4ONuz7j+2jHHb0ZxNSIJY0MZr03uqyXkvjt6mazCEjztrVkwqGZ2KLWgiC+Oa8TEkoG98Lb/YwMrCAJvHDtOVmkpvvZ2vNW/b421pxNjWXlTUx74adBgAh8yKRCqZu3cy83A1tiUX/tPxMrIpMbxD+4c4URaBEZSGT/2mKYldpRqFR+E7OJo+h0AFvkNZmZT7d4lgKyKPD4JX0t0SRIAXexa8azfJByMbbVi9ZFTmc2NvGtczwsmuTxJZ4y1oQ2Oxk5I0Ag2NWoEQY1KUFOpriC7MousykyyKjO5kqsRqcZSEzrYdmKE62icTPRnaf6MvbE1n7Z9gWUhq4kpSeaNu6v4uM2zNeb7PIyfpSszfPqwLu4sX9w/QBcHP8wNambsJRIJiwJ782zwdjbGXuNp/x5YGtbcDI+uEjwX0+PJKS/FwbRmFqiPp7dG8CTFM6t1zdLIls5OGMpk5JeXk1hQgLdtzfff38lBI3gytft4PKoyPNlFpZRVKjD700OFukraLB96EFBUUoGdtbaJRbXgkStUKJWqGsLmYaRSCTKZFJVKjaKRs3XqS3WGx8BQ9kjLd+HhDI8oeET+eS4OX4KVlVXdgY+IoqIiXFn+t13vv8b/lOC5ceMG/fr9sWlcsmQJADNnzmTdunX/0F2JiOjn0LrzCIJAx/4t8WhW/81hXVRWKB5kd6Ys7N+gjYVKpWb7eo0z28QZPTDWYQX9MAUFZezdcxOAmbN7652enpNXwq6DtwBYODNI5xPptKxCth/XOMotfqKPVky5XMG3uzWCZc7QLnhUzSupJiI1i62XNDN13pkwAJOHBj4KgsAHh05TplDQsYkb07u0q7F2d1g4p2JiMZTJ+GbkCEwN/3jd6SXFLDl1BICnWrVjrH9Nx7U1Ydc4kHAfA4mU1UHj8LKsufH9OeoyW+NvauypO4+n658MCuRqJa/f3syl7EhkEilvtxrPCPeam+tq7hZE8en93yhSlGJpYMazfpPp5dC+Xhm8QkXBA5ETV/qHM5lUIqOZuR8eZp64mrrjZuKOm6kb5gba/VUPU6osIa40lriSWOJKYogvjaVCXcGV3Itczb1MD4dejHAdg72x9rBYXVgbWrC8zXO8F7qGsKJY3gv9iRXtl+BsYq8zfq5vP05lhJBclsv2xCvM9u2rFdPfNQBfSwdii3M4lnqfid41yzN9rOxoZedMaF4m59LimOBb02yjl4fGne9GRipqQUD60PtsbGBACydH7qZnEJaZpSV4mjlp7js+V9uJzdrMBEsTY4orKskoLKapU80+NccqF7bcolKdr91AJsXc1IjScjklZZU6BY/JQ9/dikolFnoED/BA8KjrYVrwwFa6ESmeyqp+orqyxo2htFDjWGculrSJ/AswMzDCzODvM89Q/o3X+i/yPyV4+vbtW+c8BxGRfwvlJX9YUY+c3TBDgbo4tecGRfmlOLnb0kVvnB0AAQAASURBVHuY7kyKPi6fjSAlMRcLK1OGj+9UZ/y2rcFUVCjw93ehe3f984M277xKpVxJywA3enTWtl8G+GHHRZQqNV1aNqF7G+0G/c0nb5GRX4yLnSUzBta8N0EQ+GTPGdSCwJC2/nT3r2kjfSw8mnPR8RjKZHw4alANYZZRXMxHp88C8GLP7jR3+iN7o1KrWXzyEAWVFbRycOatHn1rnPdCWjyf3dasfbfLQLq51MxIHE4J46swjaPbW22HMti9Zn+TUq3izTtbuJQdibHUkM/aP0EPR+0smSAI7E09w9q4/ahR42vhwVst5uoVAw+TW5nDkYyDXMo5j0rQPMGXICHAsjmd7brS3rYTFnWIG12YG1jQ2rotra0184/Ugpr40lgOpe0ntOgeF3POcyX3Er0cghjuOgpbI23ziT9jZmDKe63m89rdlcSXpvJVxCY+bfu8zjI5Y5kh85oNYNm97WxOuMCkJt2w+FMGRyqRMKZJG1aEneZgcqiW4AEIcm9KaF4mF9IStARPoL0jpgYGFMvlxObn4mdXU7z5OdhzNz2DmFxtswUPG03ZWkq+bmMFBytziisqySkq1RI8VlW1/8XllajVgs4HCabGhpSWyymv1G1KYCB7qFRNVXvm5sG/nfXQMNVZIMNG2EqXV1lHm5o/+v7ZojyNOLSya/hnWURE5P83/2mXNhGRf5ITWy9TUliGm48TXYc0TJTUhlqtZndV/8242b2R1fJU988IgsCWXzUOaqMnd8Gsjk1JXl4J+/ZqsjuzZvfW+8Q3M7uI/cc0mZenn+ylMy48LoMTwZGaQaTT+mgdzy4o4bfjmj6hxWN7Y/KnhueDtyK4nZCGqaEBr4yqub6ovIKPj2h6peb36kxTxz82l4Ig8PbxkxRXVtLW1YW5nWsKqZ/uXOdaegrmhoZ8N2gkxrI/rptUXMBz5/ehFgSmNGvDdP+am+kbOUm8dmMvADObdWWGb01HN6VaxbJ72zmfdR9jqQErOj6lU+xUqCr5PGI9v8TtRY2a/k6d+aLti3WKndzKHDYlruPt0Nc4n30GlaDCx9yXqZ7T+azNNywJeJ3ejn0bJXZ0IZVI8bXw4wX/l3k98G0CLVugElScyz7NWyGvsStlG0p13bNezAxMebvF05jKjAkrimVf6jm9sYNc2+Bj7kiRopxtibpn7gz30JR0Xs1OIEuHRXVvV424vpgej/pPD80MpFJaO7oAcDtL25ygmb3mdxCdo0Pw2GrKWVIKCnU+jHO01GRxsoq0y9aszDTfPUGAknJtBzkAk6osiT7BI5VKHgil+vbm1Cdro6wWPI0wHSgv0bwWs8cwJ6e4QCN4LG3N64gUERERqYkoeEREHgMqlZo9P2me+o9bOPCR1rJfO32f1PhszC1NGDyxc4PWXr0QRWxkBqZmRox7Qtsd7c9s+f0KlZVKmrdwo0tX3VkbgA3br6BQqmjfypMObbR7MgRB4Lstmpk5w3q2wN/LSSvm+/2XKa9U0NrHlcGdapoJlFRUsuKgZv38gV1xsanpHLbi1CWyS8rwsbflmd4135PdYeGcjYvHSCbjs2FDahgNhGZnsuK6pjTwvV4DajStV6iULDy3h0J5BW0dXHm/6+Aam8W44hyeDd6GQq1ikFsgr7ceVOO6akHNR6G7OZkRgoFExuftp9PZXvs9TC/P5uU7X3M++xYyiZQFvhNZEjAdY5n+8gVdQifQsgWvBLzBG82X0d95EDZGNnrXPwp8LfxYEvA6Lwe8gZ+FP0pBwbGMw3wT/QXFCt3DNB/GxdSeuU3HArA+/gBJZdqzbkBjYDC3mcaM4PeEixQrtG2aPc1taW/ngRqBI6naM3c6OLpjZmBITkUZ9/OztI63d9aYE9zRMW/Hz6FK8OjI8LhZawRPSaWcQh2ixcFKszHP0VG2ZmRo8EDUF+lxX6p2J6zQI3iAB2Whj3K+TrV1tb6eoNooe4wZnuKqDI+ljSh4REREGoYoeEREHgPBR++SHp+NhY0Zg6Z0f6Tn3lWVoRk+rTtmFvVv3hUEgc2/aNaOmtQFKx09AQ+TnV3Mgf2afptZs/vofTKcmp7P4VOhAMzVk925eDuOWxEpGBnKeGaCtjV3RHIWB4LDAHh5onYj/48nrpJTXEYTBxueCqrZ+3IrKY2tN+4B8P6ogTUGjD5cyra4Z/cHT+sByhUKFp88hFKtZlhTPyYG1DR++OTGacLyMrEzNuXHoHGYPJT5yassZf7lLRTIy2lr684XncbVcFoTBIHPwvdzOO02MomUT9pNo7tjTREHEF2cxMt3viahNA0bQ0s+afM8o9z1v9cKtYL9qXu0hM6rAW+yJOB1/C0bZk3+KAiwDOSVgDdZ4Ps8xlIToooj+OT+e6SU1T33bKhLDzrYBqIQlHwduelBOd6fGeDSGh8LJ4qVFWzVk+UZ6alxYDuYHKJ1zEgmo3tVKeKFNO0ho+2cqgSPjgyPn72mxC0xvwD5n8rGTI0McTDXfI9SCrTd2ByrBE+2nj4d6ypjgroEj74MD/xhOV3XfJ3qDFR92nKqS9oM/mUlbQ8yPHai4BEREWkYouAREXkM7F59AoARs4IweYT/8EfeSyb0ejwGhjJGP9WzQWtvXoklKiwVY2NDJkyvW4Rt+f0yCoWKVq096NjRW2/cum1XUKnUdO3gQ5sWHlrHlSo1q7ZpSvCmDumAi0NNVxtBEFix8xyCAEM7BdCmac35MnGZuWy+oBFeS8f0rSFo5EoV7x44CcD4di3p4u1R47zv1FLKtjz4HLEFeTiZmfNJUM3szZHECDZEagwYVvQahav5H/esUKt44eoOkkvz8TS3ZXX3qZga/NGgLQgCX0ccZk/yNaRIeL/NJPo61zRBALhXEM0b976jUFGCr4UH33Z4lVbW+rNoCaVxfBz+LgfT92oJHT9L/c55fwcSiYQOtp14o/k7OBg7kivP4bOID7lXcKfOdYv9n8DcwJSo4iR2JJ/UGSf7P/beO7yN68wePuiFaOy9F0kURVFU77KqJffe4sROdZyysePdbDa7qd9usvtLHKdsnGY79saJey8qtjrVJZJi772CJHrHzHx/3AHAwQxAQqLTPOd59DiZe6dgUHjPnPOeVyLFZ0uJyvNCfx08Ag34rs2thBQSXLaMYtDJj9wO2doECQ+r8HRMm+EJcMlFtl4HnVKJIE2j38IPJ8hNJnU8I1Z+HU/I0mZ2CBOeUB2PzXVlljYgosIE563wJGBpuxLC42YJj0Ak/dXCPkOsgaLCI0KEiEQhEh4RIhYYPU1DaDnTDZlcuvBR1H8gxGHr9TVIyzImtO+L7L77blsJ0xxFvzMzTrz3LqnJiafuDI1acOgYsRB9+l5hAnbgVBv6R2dg0Knxyev5FrwTzX240DkMlUKGr9yyiTf+P28dR5Cmsa2yBJuXcIMO/u9sPbrM00jWavDPuzdzxt5t78CRXhJi8KNruVa2U8ODeK65AQDw4+17kayOpD6Nuuz4xmmS2PbQ0nXYllvCOe7jLYdxfmoQSXIlfrP+bqSquYuvp3oO44UBYpP796pbsTt7Oe81XZhpxXeafw0P5UO1sRw/qv4K0lQm3jyAqDqvD7+MH7Z9H6PeEejleny+5GE8UvEvf3WiE40cTR7+bcl3sVhfCR/tw5M9P0eD5VLcfdJUJjxUejsA4MXBg5j2Cfet2ZFVhTxtChxBLz6caOYfR63D+gzy+Tg02s4b35RDxs5PDiNAc9WQbJ0eGdokUAyDtmkzZ0wikaA0ldSE9U7ziVSuiZDhUQHCk2og6s+Mwy34mvRsHY/DI6zwhCxvPn/suijZPC1tkeS1uNMARHrpXInC42XJ20I+6AkhRHgMosIjQoSIBCESHhEiFhjvPUtqTTZeV4vUbNOCHdc67cSJ94l1K1F1p6ttFJcv9kMmk+LW+/iWsmi89uoFBAIUKpfmoqYmdo+r5185A5pmsH5VCZaUZ/PGgxSNp98gvW0+ed1qTm8RgCSk/fINkmR39zUrkJ3CVX/qOvpR19EPuUyKf76Rm3Q3YXfif4+RYz+2azOStRHSYvd6w1a2L61bG67DAABXwI9/ObofAPCJpcuxJb8oPEYzDL5e9w7sfh+Wp2bj6yu4JOrQSDue7joNAPjRyptQauA2m3x7+CJ+201qt76+5Hpcn8fvcVQ31YgftPwOfjqAtalV+N6yh6CVC8fs9rv68J+t38H74++AAYM1Kevw3aU/xKqUtVcUGfyXgE6uw1fLv47VKWtBMRR+0/vLOUnPNRmrUGkogZ8O4IXB/YJzpBIp9uWQ0IiDY42Cc7ZkkhTB02a+ilNqSIFeoYKfptBp5ffNKU8mn5FeqwCpYXttjDn44QMhS9uMm19bZFCzhMYrrOCoFPEJTSiQIERWhBCyqknjfB4oig4fYz6qjddLFDSNJnGVxsn2ytF9BL1yLGZSG5ac/pfrfSJChIh/DPxdxVKLEPG3DrfDi8Mvk0X4dQ/wk8iuBvtfPItggMKi5fmoWCbcoT4WXnueLNK37FqKjDmUIZfLh7feJAvUu+5eF3NhPTpuxYEjpO7mk3cKW+Ter2vF8KQNyXoNbt9Zwx8/147u0WnoNSo8uJur/gQpGj9+i5DHezbWoCDNxBn/yQcn4PYHsDw3C7cs51rGfnz8JKbcbpSkJONza7hWtv85cwLDDjty9Qb86zouifpdyzmcHh+ERq7ATzffAIU0sjgcdM7gXy++CQB4sGwdL366fqYPP2x5g4yXbMNdhXxieXjiPH7a8Txo0NiSXouvL7ofcil/AcowDA6Mv4c3Rl4BDRp6uQGfKPwUViTPHSMuhADtw5RvGPbAFOyBadgDZvLf4DR8lAt6RQqMigwYFenknzIdJkUm9Iq5Y6aFIJfK8eniLwAAzs+cxW96f4nHFn0TpbpywfkSiQQPFN+Af2n8GfaPncbNedcgV8MPttidvRy/7f4Q56d7YPE7kazkKpUhhefC1CD8VBDKWXVXEokE1alZqBsfQNP0OJamcPtilSanoG5kED0ChCfHQEIyRu18FSclRHhcfBVHpyGEx+nlW/AAhPtI+WLU38hYVZJmYqs34dqcGP2xAHCajc6H8Hjc5HrVV2BLc9kJ8dPNUSOYKKggBfs0IZwmkfCIECEiQYiER4SIBcTR187B4/IhtzQT1ZsWzm5EBSm892dCpK7/xNwKzWyYJ2w4dpBYgG6bx77vvtsAl8uH/PwUbNggvEAFgOdePgOKZrC2thhLF+XwxoNBCk+/cRYA8InrVkMT1eDUHwjiybcJEXtwz2oYotSf1883o3tiGkatGl/YuZYzVj80ircut0MC4N/3XcPpYVI/Ooo/NRIl7Ae7d0I1q+bnzOgQnm0m9UD/vW0PdMrIgq55ehw/biChDt9etQMlhshi30sF8NWzr8AZ9GFFSh6+XrWDcz0j7hl8o/55BBkK2zOr8IXynbz7sX/sFH7Z9SIYMNiZuRZfrbiHE3QQgo/y4f8Gnsa5GfJ+r0peg3sKPgm9Qs+bGw+OwAy6HOfR4TiLXmcjKCZ2Hci4t1dwe7a6DLUpu1Fl3AKVLLEFrEwiw6eLv4AgTaHeegG/630S/1H5AyTJhe1IS42lWJVSiQszrfhj/3v4xpIHeHMKktKw2JCLdvsIPhxvxu0F3KTBCkMGUlVJmPa50DAzjDVRDWCXpWajbnwAl6fHcHc512pYYiLvtzDhYW1rDn76XGoSUeemhQgPq/DEip2er8ITpGIrPCHlJp7CEwhEjq9QzP1n38sSniupwwkRniTDwio8tmknGIaBRCKBMVXswyNChIjEIBIeESIWCAzD4N0/sAlqn4pd93IlqDvQDPOYFYbkJGzZx68JiYc3XzgLiqJRvbII5Uv4xGQ2AgEKr75MeuHcedc6wWaIAKvuHCYk6oG7hUnUuydbMWq2IdmgxW07+Nf88vHLGJuxI92YhLuuqeGMubx+/HI/IUMP7VoLozayeKJpBv/5/lEAwK0rlmJZblZ4LEjT+PYhYim7rWop1uZHlDBPIIBvHDkAALhnSTU25UUal3qDAXzt5NsI0DR25ZfzFsP/2XgAbbZxJCu1eGLN7Rzlxxn04uuXnoM14MZiQy6+W307r4nm4Ynz+EXXCwCA63M24wultwk22rT4Z/Cr7p9hwN0PqUSGu/Pvw7aMHbx5sTDlG0ab7RQ6Hecw4unkjGllRpiUGTAoUmGQp0GvSIVBkQaVVAtHcBq2gBk2vxm2gBn2gBm2wBTGvN14d7QbB8efxlLDJtSm7EGupmLen22ZRIYHiz+LkdYhTPom8Fz/03io9Msx9/9k0fW4MNOK4+ZLuD1/B0p1fCVzT3Y12u0jODDWyCM8EokE6zOK8c5QM05N9vEIT3Ua+axcnuKnsZWGCI+FT3iy9YRsjgkoPKmswjPt5BMevZoQBkcMhUcVqtEJCBMeWdjSFlvhCROeeSo8cvncTnaP58otbQ4bq/DohW2aVwqrmdx7Q6ouod5jIkSIEAGIhEeEiAVDZ/0AepqGoFDJsevuhYuiZhgGrz3Nxkl/YgOUKsUce0Tgdvnw3mukceh81J0PP2zB1JQDqak67Ny1NOa8udSdQJDCM28SdeeT1/PVHafHh6f2nwMAfOH69dAoueNPHTmPGacbhWkm3LWeSz5eb2hB8+gEdColHtnBrWV6vr4BbZNmGNUq/MtWbv3NExdOYcBuRXaSHt9cz7Wy/fDiEXTbppGuScJ/r9/LWZC/MdCIl/ovQQLgJ6tvQZY2YqehGBr/0fgiep2TSFPp8ePaT0Ad1T/n3HQLftrxPADgxpyt+HzprYIL/h5nN57s/jnsQRuS5Do8VPoVLJpnzPS4pw/HzS+g3X6asz1HU4FF+jVYZFiLdFVBQiTcHbSj0XoY9ZaDmPINo8H6ARqsHyBDVYjNGXdiqXHz3AcBoJZp8LmSL+JH7T9AvfUCjpkPxyRxpbo8bE1fiWPmi3h+4H18e+nneXN2Zlfj5x370WgZwLjHiiyNiTO+Ib0E7ww147S5F18DNzRkWSohPB1WM7xUkBM1XppMCM+A3YoARUEhiyyqs1lLm1ANT8jSNu3i1/CEFJ4ARcEXCIYVnRBCiYOxCE+of9d8anjiWtr8kdS1+XwGrsrSxtbwJBkWlvBYWMKTnJ6Y0ilChAgRgEh4RIhYMOz/P5KCtumGlTDMkYKWCNrrB9DROASFUp6wne3Q2/VwOb3IK0zDmk2x7WkAWTi9/CIhKbfethrKGF3Wxydtc6o7751sxdiUHSlGLW7dXs0b/9PhelidHhRlJuPG9VxiNWlz4rljhKQ9cv1mKGY9zXX5/PjphyQB7eGt65Cmi9ijpl1u/PQk6dHy2ObNSNVGLFht02b8vvECAOAHW3bCoIokSJ0ZH8SzbAT1jzdchxR1ZL8exxS+2/AeAODLS7ZiYyY3NvrXnYdQZ+6ASirHj2vvR4aaWx/Vbu/Hj9qeBg0a2zNW43OltwguOM9On8az/b9HkAkiT5OPh8v+CWmqdN68aEx6B3Bs8s9os4d600hQpqvFIsNaVOjXXHENDgBo5QasT7sZ61JvwpC7DZcsB9Bqq8OkbwCvDv0/DLs7sSvrAUglcz9tL0wqxq25d+Ll4T/j5eEXsNy0AslK4Wu7t/BaHDNfxLnpFkx6Z5Ch5s7LVBtRk1yIeks/jky04J4iLundwNbxXJ4ZhSvoR5I8smjPSzIiWaWBxedBl3UqTIAAICtJD41cDk8wiGGHndOENkdPSK7Z5YKfoqCcRYZSWEubxc1XeJJUkXM7vX4e4VHPofCEQwuY2ISHmoelzc8eP9Z3OhrhaOkrCS2wkfugW2BLW4jwiPU7IkSIuBKIKW0iRCwAfB4/jr1BrGDXfoIfrXw1eOuPZDG77cYVMCXgXWcYBm+9RK7p5rvXhp8Wx8L5873o75+CWq3A9TfUxJz30lsXQdEMaqsLYtbu/OEtot7cf93qcC+REBweH57/kBCML1y/PtwpPoTffngOviCFmqJsbF/KJRh/OH0JUy43CpKN+MQa7jU+UXcKTr8flRkZuLO6inMfvn38A1AMg2uLy7GzKHJMLxXEv50hqWD3lNdg66wI6gBN4Z/Pvw4PFcD69GJ8cTFX0Tg83oxn+4jy9u9Vt6HSyO1BNOox4/stv4WPDmBVciX+qeJeQRvb+2Nv46m+XyPIBFFjqsW/LP73OcnOlG8Yrw79P/y6+6ss2ZFgqXEzvlj2C9xb9B2sTLn2qsjObEgkEhQkVeLmvEfw6OI/YFP6HQCAs9Nv4sXB/4SPEo5cjsbOzD0o01UgQPvxxsgrMeflaTNRZSwFAwYnzPWCczZlEOXrwnQPbyxba0S6WgcaDDpsE7zXUmYkaWx9dq51TSqRIFvHprG5uLU6Jo063L3GFhUhrWNJjScQBBVlPZNKJWGlKEDxgwlCHCUWnwlFTceyqzEMA79/bjLj8ZD6LbVmfupwOGntCkiL3UJ6DhmSFzY6enrMCgBIy06OP1GECBEiBCASHhEiFgCn3muA2+FFRn4qlsUp9E8UlikHTrJR1DckqO7Un+vF8MAUtEkq7Lhu7rqfl14g6s5119dApxNe6NgdHrx7iFzPvbeuEZxz4HQ7qd3Ra3DLNXx154Uj9XB4fCjJTsGu2grO2MiMDa+ebQIAfPXajRw1ZNrpxlOniErztR0boZyl/LRPmvHiZbLfv2/fFk63AoDXO1txfnwEGrkc/7GRa3H65eVT6LXPIEOjw7+u3MYZ+03HSbRYx2BUqPHfq27mBAz0OSfx/SayaL+3aBP25HDvr83vwHeafh1uKvqvlQ8KprG9M/oGXmcX/7sz9+Gh0q9ALYu9yAzSAXw4/iye7PoyWmwnADBYYtiAh8p+gdvy/xnp6tgR4gsBtUyH7Zn347b8f4FcokSX4wKe6f0GrP6JOfeVSCS4M/8eAMDp6Tr0u/jR0SFsTSdx3sfMFwXHV6UQ0nrJ0ocgzScSlUai3LRZx3ljRXqyYO538JuIZmrJIn3SxbWuSSUSGNXkfbF6uYRHo4iQCI+AUhMi9EKEZy6ECJRcJqyi+WeFHajiER7Woqadp2LjYIMH9Ana0miahs1CCLBxAVVuAJgaJe9XWo5pQY8rQoSIjwdEwiNCxALg0AtEhdl557o5lZREEIqiXlxTgPKqvLl3mIU3WQKz47rl0M7RBLCjYwz19QOQSiW47XZ+c9AQ3ni/AR5vAGXF6VhdU8Qbp2gaz7xFznvvvpW82h2Hx4c/fkDUnc/t5Yci/PrQWQQpGmvL87G6jFuw/r/HzsDtD6AqJxPXVkaIEsMw+K8jx0AzDK6tKMea/Mh9svt8+K/TRIX5ysr1yNVH7DBtlkn8upkkoX1/zS4YlRGi0WIZw5PtxKL4nZp9yNRE6ga8VADfangBbsqPlSnF+HLFHs51eik/vt/yO4x6zchUpeC7VQ9BI+Pf/3dG38Bbo68DAG7Luwu3598lqACFMObpwe97HkXd1KtgQKNCvwafL/0Z7ij4V2R8xEQnGkuNm/Cp4v+CTp6MSd8Aft/zGIbcbXPuV5RUgrUphLi/PPSncP1JNDam10AmkaLHOYxhN59MVRiyoZer4Qr60OngBxAsMRHC0ypEeAws4bHzCU+WjrzPEy5+rY5JQz4ftijCo1bIw+qP288PJ1CECU/8xqBCoNh0NrlMWOHxzZPwuNmUOO08a3JCwQOJEh6nzQOafZ0LrfCECY+o8IgQIeIKIBIeESKuEuMDU6g/ShZ7O+9auLACKkjh3T+RBXmi6s7wwBTOniApXTffvXaO2RF1Z/uOSmRmCvfp8fkCePUdQlbuuWWNYC3KB2c6MDRuhUGnxm07anjjIXWnOCsFO1dylbB+swVvXWgFAHzlWm5dxsC0FS9dJArOY7s2c4jShz29ODU4CIVMhm9s5fY++un5Okx53CgxpeCzyyM9bCiaxr+efh9Bhsbu/HJcWxiJEPdTQXzj4hsIMjT25C7BvjxujdHPO95Dt3McKcok/GD53RzlhmJo/Lj9ObQ7+qGTa/G9ZV9EipJfcxBNdvZk7ePNiRwziOOTL+Cpnscw6RuAVmbEnQXfxN2F/44sTXHM/T5q5Gor8NnSnyBLXQI3ZcNzfd9Ck/XonPvdknc7FFIlupydqLcKKzhGhQ4rkolt7dgkf45MIsWKFPLazwvY2ipNpAlum41PeApZhWdAQOHJYBWeCbeLf00xFB6JRBIO3fAIxEuH1JmAQK+duQIEgqwqJIuh8IQIj0wmhTxOcllY4dHGf/ARQsTSlhjhsc2Q+6bVqaFULWyJ8BRraVvIZs4iRIj4+EAkPCJEXCXee/Y4GIZB7bYlyCnhN0u8Upz+oAXTEzYYU5KwaW9iUdRv/PkMGIbB2s0VyCtMizt3dNSC48fbAZAo6ljYf6QFFpsbWRkGXLOR32OIphk8w9bu3LOnFklR9hmH2xtWdz6/bx3HdgYAvzp4GjTDYOuSYiwvzOaMPXG4DkGaxpayIqwrjig/forCD48QBefTq2qRb4qQtdapyXDPne9t2s4pNH+u4xIap8agV6jw/bW7Oef6edtRdNnNSFUl4bs1+ziL0qMTrXhlkJDD7yy7A2kqbmLUH/vfw+npy1BI5PiPpZ9Dvpbb3BJIjOyYvYN4pvdfcHTyT6BBYYlhA75Y/kssNiwcsb4aGBRpeKDkR1hsWAeKCeL14Z+i2yFMYkJIUaZid+ZeAMCrwy8iQAv3BwrZ2o6aLwoqQatZW9uFaX4PoUpW4em0TyIQZXmLa2lLIjasiagaHgAwqYUVHgBIYglPPIUnGCdaOhbCCk+MGh6vjxCeeOoOALgT7KsTiZZOrIbHNkOUMWPKwqo7wGxLm6jwiBAhInGIhEeEiKtAwB/EgT+R1LDrHty2oMd+53kSMXztXWsTelrqsHtw8O0GAMCt982tDL32ynnQNIPVa0pQWipM2GiawYtvkvqZO29cJfg0+djFbvSNTEOnVeHO3St4438+0hCu3YlWd7rGprC/oQMA8OVrudfcPDqB91s6IQHw9Z3cQIjn6xsxYLUiTavFQ2sjNUUMw+C7Jw+DZhhcV1qBzflF4bExlx0/rj8OAPhG7TZkaSOk5fLMCJ7qJPf9+yuuQ4oqsnAze+34/5pfBQB8omgz1qdz64/OTDfhpaGDAIB/qrgHVUZu4AJAAgrmS3YaLR/itz2PYNTTDbU0CbfkfR23538DSXJhBe6vBaVUjTvy/xU1pp0AGLw29GM4AvxeNrOxJ2sfDAojzL5J1E0dF5yzLnUZlFIFRj1m9LpGeOOrUknARKO1n1fHk6c1Qa9QIUBT6HFMccZCCs+01w2Hn9sQNEJ4Yis8Fg8/fjpUx+MJ8MlbuIZHQOEJIZa1L6LwCP+p9vvJ+eYkPJ6QwjM34WEYBk7HlVnaQgrPQhOeYCAIq5mQUNHSJkKEiCuBSHhEiLgKnD3QCNuUAymZRqzbwy/Qv1KMD82g8XQ3JBIJ9t4dW3URwqF3GuDzBlBclonlq4riznW7fThwgFjFbr9DOIQAAM5e6sXwqAW6JBX27VwmOOf59wghumNnDXRR1hmPL4AXjhC15XN7+erObz88C4YBdi0rw+JcLun6+WFSH3VD9WIsyoqklzl8PvzqDLH8fW3TBuhnRU0f6OvCubFhqOVyfGvDNs7x/uviEbiCftSm5+Leiprw9gBN4VuX3gYNBjfkL8POnEgPHIZh8P81vwZ7wIPFhlx8sWIX55gT3mk83vFHAKTXzjWZ/Dqow5OHwgEFt+beGZPsMAyDE5Mv4c2Rn4FiAijV1eKL5b/EMtPWBW1mu5CQSKS4LueLyFaXwUu7cHD8qbjz1TI19mSS139muk5wjlauRo2JkMpGaydvvFiXAa1MCS8VwKCbS2okEglKdETZHHJylRy9UgW9gnxWJj3cWp1kNVng23xCKg4hC16BYIJIEltiKk6QCoUSCP8pDlnW1ErhdDWXe35ExmEnr0cfI4xkNjxuP/yscmRM1s4xmwsLS0oWuleOecQChmGgVCtgEvvwiBAh4gog9uERIeIqcOB5sljbdc+GBe3+/cFrhDwsX1+KzNz5P9FkGAbvvkKiqK+/Y/WcC+RDB5vhdvuRn5+ClSuLYs57+W1iU7pu1zLBpKemrlE0dY9BIZfhjl01vPHX65pgdXmRl27EjlquutM7MY0DjWRB+4VdXHJXPzSK4939kEkk+NJWro3rqfMXYPF4UZqSgtuXRWKofVQQPzxNVIPPL1+FHF2khubU+ADe7m+DVCLB99fs4vQuebrrNDrtkzApNfi3aq7N7Y3h8zg91QmlVI7vVt8OhTTy0xmgg/jvtj/AFfSgQl+AT5fcxHv9DZZLeHGQNB+9PvtmXJt9HW8OANAMhfdHf4OLFhKVvTHtNmzPvB+SOGEG8UAzFGZ8HRhzX4AzMA4GNAAGDBjyX4aBXKpGjnY1crRrIZdeee8UmVSB63O/hN/3fB0tthOoNm1HuX5lzPlrUtfhleEX0Ovqgdk3iXQVX11cZirHuZkWNFm7cGveds6YVCJFqT4LTdZBdDvGUaLj2gdzk0xotIxgxG3lHTdVrYUj4MO0141SNqYaAHQK8tl2BfjWtJAl0h8vXlrgdYaahsoFwkzC/XEUwn+KQzVB6hgKr8M5PyJjZ1PXDMa5FRvLNCGBao0SmnnW/IQwPUl65aRmLGyvnPFBQmgz8lL+Zkm/CBEi/rYhEh4RIq4Q5lELLh5uAQDsviexUIF4oGkah1jCs+u22IlpQmg434fhgWlok1TYvje+4sQwDN54gxCZG2+qjbmQ6Ok340IDSXC7ZR/fqgYAz79PjrNnw2Kkmrh2lkCQwv99QMY/tWuVYN8dhgG2V5ViUQ63/8wvjhB72S01S1GYagpvn3a58fQFUg/0yKYNnMXk/zU3YMBuRYY2CV9YEVGtAjSF75w9BAC4r2IFqmY1nex3TuOXbaQW6JvVezhWtmH3NJ5oJ81HH67YzVtYP9v/DjocA0iSa/CNxQ9yyBAADLkH8VTfr8GAwbb0Hbgh52be/SPX58OrQ/8PnY5zACTYm/15rE4VJkaxwDAM7IEBjLkvYsx9AeOeS/DT/HqUaHTYXoNMokKOdi0KdVuRl7QRKlnii9ZsTSnWpt6IM9Nv4L3RJ/HF8l9CGYNEGRUmLDZUos3egnPTZ3Bdzo28OcuMZQCAFlsvKIbmRIMDQJkukyU8E9jNLftCrpZY/4ZjEJ5+hwXTXq51TceqOA6BWpwQ4fEF+QpP6LsjZE2j2G1CvXT8rM1NpRB+WOLxsgqOWljBcbqIJU83RwpjmPDMw6IWIjzJCfT8CiFMeGIEn1wpxgcI4cmaox5RhAgRImJBJDwiRFwhPnjhFGiawbL15cgt5RenXymazvZicsQCrU6NDbur5t5hFt5+mYQG7NhXPWcUdUPDIAYHpqFWK7B7j7BNDQBefouQr81ry5GTaeKNj0xacexCNwDg3mv5T/TfO9eOCYsTaQYtrl9XyRkbMFvwfj2p3fnCTm6a3IWBYZzqHYRCKsVDW7h2uyfPnoU7EMCyrEzsqYgoRjafF7+4SGxuj67eiCRFZKH4fEc9umxTSFZp8PWaSBNRhmHwnfp34acpbMwowU35kXtBMTS+1/QKPJQftcnFuLuQS2zPTDfh9eHDAIBHKu5DliaVM24P2PC/3U/AR/uwRL8UdxXcJ0gs3UE7/jzwA4x4OiCXKHFr/tcTCiagaD96HO+j2fI8HIFhzphCmoQsTS1SVOWQSGSQQAoJJAAkkEACN2XGoPMEXMFxDLmOY8h1HBLIkKmpQXXKA8jWxlZphLAt81602etgC0zi2OSfsSvrwZhz16asJ4Rn5jT2Zd/AuzclulxoZWq4KA/6nCMo03Ojysv0hLR2O/hpbLlaEwBg2GXljaWqiVVrysttmqpTku+M0+8DwzCc6wn1fRJSeEJKIS1EeNiwgmgbJwD4A+RYCrnwn2K3l9ToRMe7hxAiPPqk+AqPzUZe57wID1uHk5yaeB3OzIQNAJCaubAKz8TQNAAgq0AkPCJEiLgyiIRHhIgrAE3TOMiGFey+b+McsxPDoVeJJW3r9cuhnmejQACYmrTj9DFCHq6P00snhDdfJ6rLrt1VMRuNTlucOHSMRG7fdfMqwTkvHKgHzTBYt6wQpfncBQlNM3j2IHk99+1YCVWUded3H54LJ7NV5nFJ489Zdee22irkJUeeGI/Y7Hi+gTQ//frmTZxF6a8unYXN50VFciruWBwhixavBz9tPEn2qdkCkyqy8Ht3uAVnzP1Qy+T43orrOMf7c38dGi0D0MqU+Pay2zl9cia9M/hpB7Gp3ZS7DevTuIpagPbjye6fY8Y/jUxVFj5f+iXIJPwn+Rb/OJ7v/y5m/KNQy3S4u+DfUZBUyZsnhCDtQ5f9bTRb/gh3cBIAIJUokKFehmztamRrVyFVtQhSSfyf+tVpX4PF34VB53EMOo/D4u/GuOcixkcuYonpDtSmfnHedjelVI29OQ/hhYEf4MzUm1hm3IosTYng3BrTSsglz2LMO4phzxDytdx+QjKJDEuNpTg/04ImWxeP8JSyhKcnDuERtrSRxfxMFOHRswSZAeAOBjiEWSUj9zAe4RHKHghZ2mQCCo+PtbSpYthhvT6W8KiECU/I0qbTzVPhMc5dk2MNKTxX0Dg0pPCkLLClbYJVeDLzU+eYKUKECBHCEEMLRIi4AjSd6sJY/xS0OjU235DYE/B4cDu9OLmfhAgkamd7//WLoCkaVSsKUVQWX3Eym+2oqyN1MzfdHPv6X3+vAYEghaWLclC1OJc37nB58faxZgDAPXv5xzl6uQf9ExboNSrctpmrIg1P2/DOJUKmomt3zvYN4Vz/MBQyGb6wmavu/PL0GQQoCusK8rGxMLJAHnHY8UwTsbl9c/1WzhP1n10+CZvfi8WmdNxdHon4dgZ8+FETSVZ7aNFm5CdF6qWG3dP4TRexwH1t8XXI0UbGKIbCf7f/Ac6gGxX6AjxYzLVjMQyD5weeRY+rG1qZFl8ufwRJcv4Tc5vfjGd7/w0z/lEYFRn4dMn/zIvsULQfbdaX8Vr/HThnfhzu4CQ0sjSsTvsn3F2yH3vyfonqlE8hXb10TrIDEEtWiqoCNamfxY2Fz+GWwpdQYSC1SG3Wl/HO0KfhDPAbfMZChX41Kg0bwYDGu6NPxkwh08q1qDbVAADOzZwWnBOytV22dvPGQgrPmNcKZ4AbNJCbZAJALG3R54+l8Kjl8jB5cUXZ2uJa2hDH0sYqPEINiUOWNqEaHoZh4J6D8DhdLOGZQ+FJyNI2c+WWtpmPyNIWUngyRUubCBEJ41e/+hWKi4uhVquxcuVKnDhxIu78Y8eOYeXKlVCr1SgpKcGvf/1rzvi2bdsgkUh4/667LmLB/uEPf4jVq1dDr9cjIyMDN998Mzo6Oj6S1zdfiIRHhIgrwJFXSC+WzTetgnoO61giOP5uI3zeAPJK0rG4pmDuHVjQNI2Db5EUtOtuE1ZiZmP/+5dB0wyqq/NRXJwuOCcQoPD2gUYAwJ03CR/znROt8PgCKM1LxdqqQt748x8SAnL7lmroNNz79H8nLoGiGWyoKMSygizO2G9OEGveHbVVyDZGUpmGbTa83kKakz66aSNHjfnlpTPwUxTW5eRjW0GkIeegw4rnO8m9+fdVOzj1Pr/rrIPZ60RhUgo+Ux6xkDEMg5+0vQMfHcSqlBLclMd9/S8PfYB2ez+SZMJ1O8fMh3Fq+iQkkODzJV9Cppr7+gDAE3Tg+YHvwh6cQpoqD58u+R+kqfJ486Ix4jqL1wfuwjnzT+GhppAkz8Ta9MdwW9HLqEy+CwppYlHCQjAo87A+8xvYmfM4NLI02Pz9eG/o85jx8dPSYmFP9uegkKgw4ulAv6sp5ryVyYTYt9qaBceXGMh72esc5o0ZFBqkKAmRHPFwo7Az1eRz4w764aW4JMUYsq4FuLHUEokEalbJid4nVIMjZFsLbROyK4biqJUCzUM9LKFRC8RK+/xBUGyKW5JG+DfGFiIycUILaJqBzUqInck0t8IzPUlqvlLSEiM8Xo8fdgs5z0Jb2kb7iHopWtpEiEgML774Ir72ta/hW9/6Furr67F582bs3bsXg4ODgvP7+vqwb98+bN68GfX19fi3f/s3fPWrX8Wrr74anvPaa69hbGws/K+5uRkymQx33HFHeM6xY8fwpS99CWfOnMGhQ4cQDAaxe/duuAQi//9SEC1tIkQkiIA/iJPvkIX8NbfFjnK+Eux/iSz099yxJqE0ossX+jE5boM2SYWN1yyJO5emGbz/HrGE7bu+Jua846c7YbG5kZaiw+a1Zbxxiqbx8iFCJG7ftYJ3vW2DE6jvHoFcKsXd27jnsbm9eP0cCXz41DauMtQ8OoFTvYOQSST49Abu2G/OnkeQprGxsAC1uTnh7UN2K15uJwvmr6/hEqGfNBxHgKaxObsYm3KKwttH3FY83UVUhX9ZtgtKWeTn8IS5HXXmDsglMvxL5Y2c4w26x/HnAZKi9lDZ7by6nV5nN14cIla3W/PuRKWRX4cVoH14YfD/w5RvCHp5Ku4r/B70ihTevNmgmSDqp3+DZgs5tlaejurkB1BmvB4yibACcLXITVqH6/J/jw9GH4XV34v9ww/jmuwfIVs7N6nWK1JQk7wD52few+mpN1CsEw7RqNCTJrbDniG4gy5oo5SwfC0hi1N+K9xBD7RyLqHLUBsx43dh0mvHIkPkM5EkV0ImkYBiGNgDHmjkkXuklpH/7RVQa0LWM4rmEpuQNU0q8L0MqT7R1jSKpuFhbWtaAZXG4WFrcATS0GysXU0uk0Ibo4bHwtbmpJhi19vY7R4Eg4Q4JSfPXZdjZutw0hNUacyjVgCAJkkFXYL9e+LBZXeHe/DkzqFcixDxl4Q74IdcINHxozxfonj88cfxmc98Bp/97GcBAE888QQOHDiAJ598Ej/84Q9583/961+joKAATzzxBABgyZIluHDhAn784x/jtttuAwCkpHD/Vr3wwgvQarUcwrN//37OnGeeeQYZGRm4ePEitmzZkvDrWAiIhEeEiARx6UgrnFY3UjKNWLaxYu4d5om+jjF0NA5CJpdixy2J2eQOvtMAANi2pwqqGIujEC5d7MPEhA1JSSps2bIo5rzX3yfHvGFPtWCj0bqGPoxM2mBIUmHfRj7J+vNhQoZ21pYj3cR9Wvzymcvw+AOoyE7D+nKukvVUHQlJuG7ZIk7tzpjDgVeaCUn60nquBe7nF88gSNPYnF+E1dkRlaRlZgJv9hFF6Bu1Wzn7PN58GH6awpq0QuzIjryPXsqPn7S+DQC4r2gTinSRuGSaofHzzj8jyFBYlVKJazK4C39HwI5f9/wSFEOhNnk1dmfu5d0XmqHw+vBPMORug0qahHuLvgOjUlhlixx3BMfHvoMpH3ktFcZbsDrtK1cVIz1fJCkysDfvSRwZ+ybGPZfwwcij2Jz1XRTpt8+579rUG3F+5n10Oy/A7B1CujqfN8eoMCFDlYlJ3wS6nV1hi1sIeoUWyUoDLH47htyTWGTgKonpKgPaMYpJr42zXSKRwKDQwOJ3w+b3IlMTUR1UcmEVB4jY06KVHIqJHT7gC6WtRYUPeP2R42tV/Ho8J0t4dGohwhNRb2I9/AgRHlOc2pxptibHaNRAESMNbjbME8SWlp6VGOGZGCYKW2Zu8oJGR4/0EHUnOcOAJP3CESkRIq4Wa175JaSaj/43OATaQx6C2O12znaVSgWViv8b4vf7cfHiRfzrv/4rZ/vu3btx6tQpwXOcPn0au3dz2zLs2bMHTz31FAKBABQK/vriqaeewt13342kpNgPVGw28vscTZb+khAtbSJEJIijrxEVZsvNq2J2QL8SHGDVnXU7liI5bf7N9VxOL05+QBbCu24Qjo2ejbdY69uu3VVQxagN6Ok343LrMGRSCW7YtVxwzosHiMp107ZlUEcdZ9ruwoGLxP50745azlggSOHPJxsAAJ/cwo3D7p+24EBrFwDgMxu5NUy/P3cBAYrC6rxcrMmPkJo+qwWvdRAi9OhqboDE/6snUdM3FC3hxFA3zAzjneFmSAB8s3o35xqe7T2GMa8VmWojPl16Ded4746eRJu9DxqZCl8qu5OzH8MweG7gGVgDFmSps/FA0Wd4Cz+GYbB/7Hdot5+BTCLHXQX/hkx1EeKhz/EB3h58AFO+ViilemzL+k+sz/jnvwjZCUEp02NnzuMo0u0AjSBOTvwANn//nPulqHJQrieksMl2NOa8kMrT5RT2eBewKs+gmx9OkKEmC3Ozz84bMyrJPbIHPJztEdtagLdPiNDQDLeJaDheWsi2RgkrPG62DkgqkQgGEzjccys8Rl3sRb7VRl6XKU5/nRmW8KTMoyaHYZhZCk9itrTJUdLgNSOBvmHzwUjPBAAgt0RUd0SIAID8/HwYjcbwPyGlBgCmpqZAURQyM7nfnczMTIyP839LAWB8fFxwfjAYxNTUFG/+uXPn0NzcHFaQhMAwDB599FFs2rQJVVWJJc8uJESFR4SIBOB1+3B6P6lr2XpLYqEC8eD3BfAh2xPn2jsTs8md/LAVPl8AeYWpWLIsfg2I2WzH6VOEUNxwY23MeW+8T0jR5nXlSBNYKHUPmXGhdQgyqQS376zhjb98/DICQQrLirNRVcStX3m/oQOTdhfSDUnYt2IxZ+zpUxdJalt5MRZlRvz6ZqcLL1wmNrwv89Sd06AYBtsLS7AiM9KM5cz4II6O9EIukeLrNREJnWEY/OgyCSq4pbAGlabIPkOuaTzXS5qWPrL4Omjkkafyk94ZPNtPlJ8Him9Ahpr7pOrk1DE0Wi9BLpHjcyUPQy3jL0JPml/GhZn3AEhwS96jKNLFjgMP0l6cM/8UXXZyznT1MmzJ+i50iuyY+3yUkEmV2JL1PfhG7Rhzn8fx8e9hX/5v57TTVZu2octxHs3WY7gm4xOCT//LdYtwcuo4uhzChCdfm4lGayeGBAhPuposzM1ePuExKAjhsfm5gQahxDWfUOIa+99ohSectiZoaQvFS3NJTahxqFal4L1ummbgYvvs6ATSGO1hwiNMbBmGgc3OKjyGOAoPG0Ig9D2OhsvphcdNriktwaS1yRErACTUKHk+GA4RngWM/hchYiFw7vYvw2BY2Hq1eLDb7ch+6HsYGhrinFdI3ZkNoQdv8VRYoflC2wGi7lRVVWHNmtjrli9/+cu4fPkyTp48Gfc6P2qIhEeEiARw7mATvC4fMgtSsXhl8dw7zBN1B5rhtHmQkWPCik2J2eQOhBSb62vmtJK8+04DaJrB8uUFKCoSLgB2uX04eJQoRjfvFVaMXjpIzrl1ZRmy0rg/+L5AEC8fI6Tw3u3c/RmGwXPHiTJ078YazgJx0uHE6w3kvJ/fxCWTT124AF+QQk12NjbMSmbrtkzjzS6S9PbI6kiPHIZh8N+XjgIA7i5fjiJDZBH2/kgr6meGoZUp8LVKroLzk7a3EWAorE0txzWZSznH+9+ul+ChfKg0lGBf9ibOfhPe8XDdzs25t/HilQGg0fIhjkz+EQCwJ/uzqDRu4s0JwU858cHoozB7mwFIUJ3yKSxP+fS8Etc+SkgkUmzK/He8NXA/ZnwdaJx+CrVpD8Xdp0K/BkqpBtbAJIY97cjX8u2P5azC0+/uh4/yQSXj/gEP1fEIEZ6QwhNtaQNIqAEA2KMS3MIKT5Cv8IS+Q1QMS5tQ2lqkhof7/rh9hDxolHxS6Pb5w6RKL2CLCVvaYiSweTyBcB+fhVJ4zOOENBqM2oQi8QFg4iNSeEZ7iaUtrzRjjpkiRPxloVUooVUk9j25GgTZcxkMhnkRrbS0NMhkMp6aMzk5yVNxQsjKyhKcL5fLkZrKrVd1u9144YUX8P3vfz/mNXzlK1/BW2+9hePHjyMvb+5Qno8SoqVNhIgEcPxNUl+y9ebVC+pT/+A1ctxdt61OyCY3PDCFloZBSKUS7IwTQAAAFEWHwwpuuDG29e3DE+3weAMoyEvBimX8mgun24f9p9oBAHfu4R/n0MVOWJweZCXrsWNFOWfsQs8wOkbN0CjkuGM9t4j9z+cvI0BRWJGfjZWFkQhsu9eLP7N9d760fi2v7w7NMNhZVIpl6REl6ehIL+qnRqGRK/DV5RGbW4Cm8NMW0ij0MxUbkKmJWAdPmztxaqoTcokMj1Vym2Cemr6MC5ZWyCUyfLXiHk4/Hpqh8Vz/U/DTflToF2Nn5rW8ezLm6cE7o/8LANiQdivWpt7AmxOCn3Li0MjXYPY2QynVY3fuz7Ai9fN/dbITglaejvUZ3wAAtFj/DFfQHHe+QqpChZ48/etyXBCck6pMg1FhAs1QGPYM8cZzNWSxO+blWypSlWQhP+Pnp/+E+ui4gtw0NgWbmBagad4+sRBk5yqiCA9F02GFRx1FeBysgpMkUL9jdxMSppDLoBKorbE4WLtajLqVaSt5vRq1Ahp17EXX1BQp+E9NndsmOzFmBQBkJFi/AwATQ6SGJyNnYQnPUBdZfImBBSJEJAalUomVK1fi0KFDnO2HDh3Chg0bBPdZv349b/7BgwexatUqXv3OSy+9BJ/Ph0984hO84zAMgy9/+ct47bXXcPjwYRQXL9wD4iuFSHhEiJgnvG4fzn9IksA237hwvXdmzHY0sDaz7TfFtpkJIRRFvWpD+ZwWlIsX+zA15YDeoMbGOCrS+x+SCOHrdi4TJHX7T7XB5w+iJDcVNRX83jwvserO7VuqIY8ib3+qawAA3LCqEkZt5Mm1NxDECxcIqXlgPffevtDYBFcggIq0VGwrifxoDtltYXXnKysjNjeGYfDEZSKd31+xAhmayJPt1wYaMOiyIFWVhAdnxVBTDI2fd7wPALizcD0KkyLql5fy4Xc9r5HXlL8T+VruwuuY+TC6nJ1QSVV4oOizHDIEAH7Kg9eGfgyKCaJCvwY7Mj/Ju2eRuYTsTPlaoZIasCfvF/NKRPtLo0C3DRnq5aCZAFosf5xzflESse4NuloExyUSCbLVJGFt0stXcZKVZLFuCzh5Y1o5UYO8FD/BSM6+F9FqTVx7GmtzU8m45CXUl0cbpdaESA0A6KPCB2xuQlqSk/ikZZq1o6XqtYLfsxChSY2RwDY1TYhM2hwNQsfHifKVOY+anDE2eCArL3HSMso2B82JoRxfCWiaxlAX6f9UuChnjtkiRIiIxqOPPorf//73ePrpp9HW1oZHHnkEg4ODeOghosx/85vfxCc/Gfmb9NBDD2FgYACPPvoo2tra8PTTT+Opp57CY489xjv2U089hZtvvpmn/ADAl770Jfzxj3/En/70J+j1eoyPj2N8fBwej4c39y8FkfCIEDFPnH6/ET63H1mFaShbPv8eOXPh+LuNoGkGi5YXJLRYoIIUDr1DyMXuOIpNCPtZdWfnziooBfp+AED/0DRaOsYgk0qwexu/ASbDMHj9MDnOzdfwCVHrwASa+8chl0lx8wZuceLojB2Hm3sAEDvbbLzT1A6L24McowE7FpWGt/spCs9eIqTu06tWcs73+8YLoBgGm/IKsTwjUtdyfLQPjVNjUMvk+NzSteHtXiqA/20j9TkPLdqEpFn1OW8PX0SPcwIGhQYPlmzjXNuLg4dg9lmQoUrBHfm7OGNTPjNeG34JAHBL3h1IU/HT1vaP/Q7T/hHo5am4MferkEiEf3ajyc7uvF8gRbVwKYALCYlEguWpnwYAdNrehDvIV15mozCJ2ANHPF0I0nwbGQBkqAmRnPDxCY9JQQiPI+AGxXDrbjRsxLRbgPCEyCc/gIC1pwkSHmJPi1ZrXH5y3UlKrpri8BKlRqOQQxlVw2NxsSqNAOGZYQlPSoz6G7OFkLvohMPwOGtVS58j4GSSTV3LnEfM9NgwsaVlJ0h4XA4PbDOEoOUU8hc/V4rxgSn4PAEo1QpkFcVPMhQhQgQfd911F5544gl8//vfR01NDY4fP4733nsPhYUk7XJsbIzTk6e4uBjvvfcejh49ipqaGvzgBz/Az3/+83AkdQidnZ04efIkPvOZzwie98knn4TNZsO2bduQnZ0d/vfiiy9+dC92DvxteCREiPg7wOGXzwAArrl97YLa2Y6wKs01N81NWmbj4pkezEw5YDRpsW5L/IWxzeZGXR1JTdu7V7gfCgC8f5goWGtXliA1mb/Qau0dR/fQFFQKGa4ViKJ++TghYLtqK3gLuRdONYJmGKwrL0BpVmRRxDAMnj1N6no+sbaGowq9296BCacTGUlJuGFJJOBg2uPGi+1EifriijWcY/3iMonbvLeiBumayNPxF/suYcLrQLbGgLuLIyqSJ+jHb7o/AAB8pnQ7jMrIdY+4J/Ha8IcAgM+X3gq1LLLYZRgG/zfwDHy0D2W6CmxL38G7Hy22E2iwfoBQSIFWLvyUXZjslAvO/VtBtmYV0tVVMHub0WJ5HqvT/ynm3BRlDpJkRrgoG0Y9XShI4pPpTBWxJE56J3hjekUSJJCAAQNbwIUUZeQ+ht4Tb5BPeGQx6nFCtTPREdMMw8AfVni45CWs8ETZOmxeNmlNIFra6iJkSFDhcbCERy9MeEIKT1oMhcfMKjzpcRQehmEwwaauZc7DphZSeHLyEouOHRuYBgAkp+mgjdMENVEMtI8CAPLLsxY0EVOEiI8THn74YTz88MOCY3/4wx9427Zu3YpLly7FPWZFRUU4zEAI8cb+WhAJjwgR84Bl0o6LR0hB/Y471s0xe/4Y6Tej8/IQpDIptl5Xk9C+obCCa/ZWQ6GI/1X+8IMWBIM0ysuzUBrDCx+kaBw8QixH+3YIR0e+cYSQjO1rKnhxuTaXF/vPs7U9W7lR1h5/AK+eJfvet6mGM3a6dxBd5mlolQrcURs5L8MweOo8qfm4v3YFpyD82aZL8AaDqE7PxIbciNp2dmIIF8zDUEpl+EKUuvO7jjoAwEOLNnOajL44cArTPgdyNMm4vSCyDwD8tvc10nMnuRLrUrmJanXTJ9Bmb4FCosCnij7Ds7JZ/RN4Z4TU7WxKvyNmIttCkh2GoeANjsIT7Ic70AdPoBfuQD88gT4ADAyqFTCqV8OoXoUkRUVMtWk+kEgkWJ7yaXww+ig6bG+gKvl+aOTCC2WJRIKCpKVos5/CoLtFkPCEFR4BS5tMIoVBkQRbwAmb38EhPFqW8HgoPy99KFGFxzerL090AEGI8Oh4Cg8hPEY1f6EfUXj4YyGFJzWWwmNl09ViNAudmofC43B44WZT1zLmkbo2GlZ4EiM8I6ydLbtw4exsADDQQexsBaKdTYQIEVcJkfCIEDEPHH3tHGiKxqLaIuQtYPHskTcJaandWA7TPFKUQrBZXDhzjET4zsfOdmA/IRvXxlF3zl7sxbTFBaNBg/WrSnnjTo8PB08TQnPLdv5x3j7dAl+AQkVeOqpLuNHJ79W3w+7xITfFgM1LuMWLz54h9+DWmqWcp+R1A4NoN09Bq1DgnuURsuAK+PFscwMA4KEVazgL3P9tIurOnWXVyNRGFoIv9F2E2edErtaIW4tqwtvtAQ/+r4/Y3L5QvhMKaeQnsd7SjgszJKjg82W3cs5j9Vvw8tCfAQA35t6KTDU3eptmKLw29BP4aDfyNIuxNeNu3v0CAIr248PRf75qskPRbow4nsew7WkE6OmY88zu92F2k1oludQAg2olUjSbkK2/C1JJ4mlDOdq1SFMvxZS3Bc2W57E6/Ssx5xZoKwnhcbUCAu6k0D2c9E0IxqaaFHrYAk5Yo+p41Kw1kQYDPx2EShZRYGIpPKH/L4sifLNjqtW8Gh5hS5uNbQYorPDEqeGJo/DQNINptqlomoDSCgCT86jhCak7pmQt1HM0JKZpOpy0lqilbZRVeBbSzgZEFJ7CxSLhESFCxNVBJDwiRMwDR14lTUF33Llw6g7DMDj2bgMAYNs8GobOxtGDzQgGKZQtzkZpRVbcuT09k+junoBCIcP2Hfwn6yG8+wFLirYvFezI/sGZDnj9QRTlpKC6nLsAYRgGr50k+9+xpZq3WH3xFKn7uWdDDcdGNDhjxbGuPkgA3L+Wew/+cJFI6rcvWwqTJrJgfKW9GTafF0VGE/YUR8hB8/Q4Toz1QyaR4AtVEaXGTwXx+05ChB5atBlKaeS1/an/JBxBL0p1mdidHVGlGIbBM31vAQCuy9kcTgkL4dXhl+Ch3CjUFmNn5h7evaozv4phTztUUi1uzf86ZDES1s5P/RyT3kYopLorIjs048eo4wUMWn+NAE2eskuggEZRBK2iCBpFMbTyEmgURWAQhM17ATbvedh89QjSdsx4jmDGcwQW72lUpj+RMOkhKs+D+HD0MXTZ30Jt2kMx+/Lks6rOiKdTcDxNmQ4JJPDRPjiCDhgUXEXCoCBKhz2a8Egj5/NSAQ7hkYJ8DqN76oQUHnnU59QTIKRGKpFAHmV3c/qJkhOL8Bg0fMIz42T75AiGFrCWNQNfwbE43KAoGhJJHAUoZGmLo/CMj4UCC+a2s01N2BEIUJDLZUifx/zZGOkjSX05C1xnM8wmtBXM8RsnQoQIEXNBJDwiRMyB8cEpdNb3QyqVYPONC5eYNdg9ieFeM+QKGdbtXDr3DrNw7ACptdmxL7ZiE8KRw8SKt3ZdKQwG4Yhbi9WF0xd6AQDX7RC2Xr13kiSiXb9lKY/QXO4bQ/+EBWqlHNeu5jYTbR2eQNvIJJRyGW5ew32dL10kJGlzWREKU03h7YNWK4719gEAPlkbIUI0w+DZJjbEoHolhzw91XaeXF/REuTrIsd6c6gJZq8TWRoDbi6MkBpHwIMXBwgR+lzZDs7T/lPTl9HjHIZGpsLdBVxCM+gewNkZst99hZ+CTMIlhxPefhwzvwAA2Jv9BZiUwopgn+MQOmwk/W1L1vcSIjsME8S48zUMWP8XPorYftTyfBSavoyMpOshjUE6TOo14f0d/lZYPHUYsP4vpt0foNX8tSsiPbnaddDIUuGhpjHuvoTcpLWC89KUJNHPQzngpVxQy7gLfblUDo1MAzflhivo5BGekPoWjAotYBAhMzzFhmb740SpNWHyoohKVfMR8mJSqXmf8Rk2cS1Fw/0OTbGkJl3HJy4TNkLOMox8FWZ8hhCWzBQ+YRkzk6CB9GQd5HL+wwcAGGPT13LikJPhEVKTkzeP3jiDfWzKWkFKwvUyQz2kV07BAvbKoWkaQ92E8OSX/3Wa7YoQIeIfB2IVoAgRc+DEmxcBAFXry5GcYPfxeKg7QFSP2k0VSNLPv9B3csyKlsZBSCQSbNklXGsTAsMwYcKzfXtsdefQ8TZQFI0l5dkoKuD78EcmrWjsHIFUIsG1G/hhBW+dJrU/u2orkBTVE+S1syw5W1bGiaL2Bym8Vk/2u2sVl7i90HgZDIBNRYUoSo4s1o4P9aPXZoFeqcStFRHyNO524O0+Qsg+syTStJRmGDzFqjsPlK3lqDsvDZ6GK+hDsS4D2zIj94ZiaDzf/x4A4Obca8LKAkDu5ytDhMysSVmPoiSuPY9ignhr+Geg2QjqZaZtvHsFAFZ/P05N/AgAsCz5U8hLWi84TwgOXxPOj1yHzul/h48ag1KWifLU72N17n5k6W6JSXZmQyKRw6CqRqHpi6jKfBISKMOkh2b4xf/xjyVFXhLpdTTkOhFznlKmgVZGFudWPz+YAAA0MqJmeCg3b0zOEssgzSU81Kz6nOiaHA9FFJtoe5ojQF6jPorwWGYRntmgGQYzbJxqahJXcZl0sLU0egHCw9bhZAkSHkJqsoUIzxQ7liZMZlxuH2xsn57sDJPgHAAYYWtycudRkzPYT1SaguLEVBqGYTDYTd7P/AUkPOYRC7wuH+QKGXISvCYRIkSIiIZIeESImAMn3iKEZ8tNC9sPpe4AUTc27hFWVGLh2CFCEpbVFs7Ze6e1dQTj4zZoNEqsXVcWc96Bw+SY124XVpreryNkYnVVAdKjago8/gAOXiA2pRvWc0mV2xfAu/Wk7ue2NVxy9kF7N2bcHmTok7C1PEIcfMEgXm4iJOm+Gm74wbNNxOZ2x+JlnOLx59ovIcjQWJOZj+q0yNPgD0c70OechkGhxh1FkR5H7qAPf+4nIQYPlmzjBA6cMF/CgHsMOrkWN+dt45y/2X4Z7Y5WyCVy3JzLjekEgHPT72DM2wONTI/rc74kmOYXoD04OvYtBBkPsjS1qEn9LG9OLEw430D92D3wBPugkCajNPmbWJN7CDn6u+dFdISQotl81aSnQLcZACE88dJ5klm1y+LnBxMAgJYlPG4BwhNS0vgBBJHzRQdHhEIIZtvcAMAZIApPdACBlY2YNqm5Ko7V4w3b4pKjFB6zk1jTMqIUHpfXHw40yDRySY0vEMQUG1qQlcL/Do+aWfUmXfj7PcbW5hgNGmi1sRW5YTZ1LW8+hKeXEJ78BPvomMes8Lr9kMmlyFnA0IKhTqJc5pRkQBZD5RIhQoSI+UIkPCJExMFsO9vG6xNrChoPowNT6G0bg1Qmxbo4dTVCOMoSpa2746s7AHDkQ6LubNhYHrNoubtvEl19k1DIZdixeTFvnGEYvH+SHGevQBT1kYZuuLx+5KYaUFuWxxk7dLkTTq8fealGrC7N54y9eIG8jttXVHGiqN/r6ITF40W2Xo9rSkvC2/usFhwZJPU+n6yqCW93B/x4vpPY3GarOwzD4HedhNTcW7IKullP818dOgt7wIN8bSp2ZUfUJYqh8Hw/Keq/LW87dPLI03yaofEq23PnmoydvJ47jsAMjk2SIIOdWQ9Ap+DbiBiGwZnJ/4HN3weNLBVbsr4HqWTuxRzDBNEz80O0T/0LGPiRqtmONXkfIM/4IGTSq48BvlrSk6VZBalECXfQDHtgMOa8ZCWpxbAEhBUerZyQBnfQxRsL2dWiLW2zCZA8ivB4WYVHwyM8wgpP2NIWlbg27SbkxKBSQRkVV212kGtN13MfBEzYibqjUyt5qucE22NHrZQLJriFFZ4YhGd03AoAyMk0CY6HMBIiPPnzIDxsHU5BgnU4g13kvcwtSodcoPbvSjHIEp6CCtHOJkKEiKuHSHhEiIiDj87ORhb71WtLYIgROyuE4YEpdLcTorR5DqJEUTSOHiXqSjw72362987GNaUw6Pk1Pg0dIxietEGrVmDbSn6dyVuniDp0w/qlkEq5isZr58ixb11TxRnrnZrB2f4hSCUS3F7LJW7P15NePvfUVHMKx59tZmO4C0tQZIyQiVd7mmHze1GoN2FnXkTFujA9iEbLCJRSGe4vjfTq8VIBPN9HrFcPlGzj1H18OHEOo14zjAodbsjdyrmuU1MnMOoZhlaWhH3ZN/Luwwfjz8BPe5CrqUCNid+TBwC67G+i13EAEsiwJfv70MjnTrUKUFY0TXwOw/ZnAAAFxoexNONXkEvjN5xMFFdDeuRSFdJUhAxPei7HnBeqZ4plaYun8IQtbcz8LW3eGJa2sMKjiFZ42BjpKEvbjIeNkNbyAwRCNTwZUZa2CStboyNgZxtj7WxZKQZBFTCk8MSytI1NsuNx6ndcLh9m2GagufOo4Rlia3jyixNTaUJ2toIFTK8EgKFOtn5HJDwiRIhYAIiER4SIOKh7h1ioFtrOdvTtBgDA5n3L40+MwnHWzla7tgTGOYjS5cZBWCwu6A1qrFxVLDgnSNE4dIzY1fbG6L3zzgm2PmfdImiiVKLxGQfOdw4BAK5fx1V/+s0WXOobhVQiwU2ruITrlUuECG0uK0KOKUIkWycm0TA2BoVUijuXRa7HHfDjlXayzwPLIkobwzB4pp306vn0ktXcEIPO0wCAWwprkKaOLDrfHr6AGb8L2Zpk7M2pCW+nGAovDBwAANyRvxMaWeTpf4D2463R1wEA12XfiCQ5994PudvRZDsGQIK9OV8Q7G9j8fXirPkJAMCK1M8jSzN3Mp83MIz6sbtg8dZBKtGgMv3nKE7+2lX1z4mHaNIzaPvNvPfN1JDPstnbHHOOSRGf8MSr4ZGx9VdUFOEJcggP9754KOHQArs/RHiEa3gMqmiFhw0s0HIfCNA0gynW0hZd2zNujR1YECY8ycKkNWxpSxN+yDIyZgUQn/CE1B2TSQvdHM1AbRYX7GwMdqKWtgFW4ckvW7j6HQAY7GIVnnIxoU2ECBFXD5HwiBARAzMTNrRfJElh6/fWLNhxh/vM6G0bhUwuxaYE63fqjhByMpe6AwDHjhF1Z9OmRYIx0wDQ2DwEi80No16D1TVFvHGfP4gj57sAAHs38c954EIHGAaoLc9FTip38fXORXKtGxYVchZ9QYrG25fJ2B1R6s6rzYRc7SwvQ1pShFS809MBZ8CPQoMJm/IKw9tPjw+g1z4DnUKJ20ojxxpyWXB0nNQVPVAWSQ2jGRovsMls9xVtgnxWiMHxyUuY8M3ApNBjX/YmznWdMB+DNWBBsjIF2zK46g3DMPhgnKgvK5J3IkfDV8FoJoiTEz8AzfiRq12HquT7eHOi4fJ3on78bniCfVDJsrAi+0WkJ107535XixTNZlSkfg8AMO54FUxUzUwsGJVFAABHYCTmHI2MfA68NN+yBkQUmugYaQAIsIlrs3slAYAryCauyQX64PjIIt6oiEpW85Lzp6ijAghcLEnRcgntuIOoNVl6LkExO10I0DRkEgkyoixtwzOEtOSl8EnJ0KQVAJCfbuKNBYMURtmUtvwsYWVmiE1fK8iNbVXr7yeKTeE86moG2bmZ2SaoNYml9PWxzUGLFy2cEsMwDPpbyeeocEnugh1XhAgRH1+IhEeEiBg4z/alKa8pRGq2acGOe+J9YvmpWV+WkJ1tYsxK7GxSCdZt5dfazEYwSOE4S3i2xpl7+CSZs2VDuWD87cmGXrg8fmSl6rG8nL/weO8cIS7RUdQMw4TDCq6v5So/p3sHYXa6YdKosWVWWIGfovBWGzne7VXc8IQX28h7cdeSZRzb0vOdDQCAm4uXcp7W/7n3Akl5yyhBiT6y4Dtp7sCQexp6uRrX50aUIpqh8fLQBwCAm3K3QiWLLPr8tB/vj78DANiXdQMUUq7K1ek4iyF3G+QSJbZm3Mu7RwDQYXsdM74OKKV6bMj8tzkVGj81haaJz8FPTSJJUYEV2S9Bp4z/ni8k0pOug0yig48ahc13YV776BTkSbwrKKzeAIBCSt6jIO0THA8RnWilBgC8FNlHLeUuyB0Bor7o5VxSwzAMZvysFU3N/Z6ZPWzQgCaK2LCEJ1vHJTajdkJAcqIIz4iVbM806Dl1aAAwNG0FAOTPilsPYXCSpKcVCtTgjJhtoCgaGpWCFxAS3j9EeOKEEfSxNTnFJXPX5Az2kljpRO1sVJBCfwexnpUuWbjmoJPDM3DZPZArZMgXFR4RIkQsAETCI0JEDJxlY6PX7p67100iOPEeqVFJ1M52mq3HWVpTANMcROnSpX7YbB6YTFrUriwSnBMMUjh+mqg32zcKL6YPnibn3L1+Ma8+p3PYjK6RKSjkMuyqreCMNQ6MYXjaBo1SgWuWlnLG3mgkAQjXLVsM5SySdbi7BxaPF5k6HTYVRVScrpkpXBwfhUwiwe2LIkRo0uPEgUGi4txbURPe7gkG8Eo/qfe5rzQSYgAAf+o7CQC4JX8NtLMUgQszrRhwj0EjU2FfTrS6cxS2gBUpylRsTNvCGaMZCh9OPAcAWJt6IwwKfk2OJziD+unfAQBq074IrTz+opJm/GiZ/BJ81Bg08mIsz/ojVPK/7KJPJlWH1aQJ5xvz2idJTuxqruBkTFUoRHgCtHBtEAOynzDhIfuoZFwlJ0x4olQcV9CPABthnaLkfl8mPaySo+ESinEnq+QkcbeP2sn2bEM04WFVnGS+9WxkmozlC9ThDLAKT2EGX8HpH2XJTFYy7zsHAG63H+Zpcv3xFR5CeIrmEUIQ6sGTaCT1cK8ZAX8QmiQVsgrmDkaYL/pahgGQ+h2FUmwXKEKEiKuHSHhEiBCA3xvAxaNsw849C0d4hnsn0dc+Bplcig1z9NCJRsjOtuEaflJaNA6z6Wxbti6O2UTw0uVB2BweJBu1WF6Vzxu3u7yoayCWvj0b+ITo3bPkejZVFcMYlTQVsrPtqCqFVhVRRJxeHz5o7wYA3Lyc+zpCdrZbllZyanFeYNWd7YWlyJi1EH25+zKCDI3a9FxUpkQKpt8dboYt4EWe1oStWRF7Wad9FJcsfZBJpLijkNv3JqTu7MvexElm46g72TdAHmWnarB8gCnfMDQyPTam82OqAeDS9K8RoJ1IUS1CueEGwTkhMAyDzqn/gN1XD7nUgKrMX0MhM8Xd56NCZtJNAACzaz8o2jvnfK08HRJIQTMBeKgZwTlhwsPEUngI4ZGAv9D3siRJLYtSeIKE8BgUUUEDPqLiaGUKaOSRz6A74A+ntM0mPAzDYMzFEhuewkO25xq4xCak8OSa+IRnaFrY0kbTDIZYhacgk094BsdY9SdH2M4WUndSTFro49Tm9LMkpngeJCYUSV04DzVoNnraRsk5FmVBKl245URfKyE8xZWinU2ECBELA5HwiBAhgMt1HfC5/UjLNqGsumDBjhuys63YUA69iZ/4FAvWGSea6wcAABvmsLP5fAHUnSTKx/Y4tT6H6zoAAFs3VPDsOABw5HwXAkEKZflpKMvnLoQomsb+80T9uW4tl7j4g0G830COfWNUWMH+1i74ghRK01JQlRMhKZNOJ4739QMAbptlZ/NRQbzeScjb3Usi9U40w+DPXUQpm63uMAyDP/USC9bdJSs5CWwvDpAQg+2ZS5GpjixC2+19aLX3Qi6R4ebcbZzrPWE+CnvAhlRlGjakbua+TtqLo2wM9eb0O6GW8VU3s6cZ3XZCmNamPzpnBPWw/WlMuF4HIMOS9J9BqxAOm/hLwKheDZUsBxTjxLTn8JzzpRI5tHLyOXEFhPvsKCQhhUeY8DCIbWnzsQpPtKXNHkPhmWYJT7IqWt0h2zVyBSelze73wRMkdUI8hcfBWtqiCM+whWzPM3FJjdPrg8VFrisvqrZtwuqAL0BBLpMiW6AHT/8YITSFWcKKycDwNACgIC92wp/T6cXkJLm2onnY1MKR1CWJBQ/0tRPCU7KAdjYA6Gsh9TvFlXlzzBQhQoSI+UEkPCJECODsQUJM1uyuFoyNvVKECM+mvYmpRicPt4GmGVRU5iBrjojZc2d74Xb7kZFhwNKlwguGYJDCiTOsnW2TMIE6cIoQGiF150LnMMw2FwxaFTYtLeKMHW/rg93jQ4ZRhzVlXOXojQZCXm6uqeTc19dbWkExDFbm5qA4JfL6PujvwYzXg6wkHbYWRBb/dWP9GHbaYFCqcH1h5PqaLKNosY5BKZXhtsJICprV78aBMUKQ7ircwLmmN0eOAQC2ZaxCiiqyOA3SQRwYfw8AsDf7ep66c276bTiDMzApMrAqZR/vHjEMjbPmnwIASvX7kKGJH1Ax46lDr+V/yPyUbyJFszHu/I8aEokUGTqiSE06357XPkny+HU8EUtbfIVHKvCnKVzDE63wBIj6FF3DM8MGFqSoooIJwna2JM5nMGRnM6nUUM9ShLyBAGbYlLbcGJa2aIVnmFV3kpM00Km5FrzBCaLg5KWbBB80RBQeYcIzyKavFcap3wmpO+np+jkT2lwOL6ZYclSQYA1PTyur8Cw04WEVnpIqkfCIEPFxRV9f34IeTyQ8IkREgWEYnP+AROuu2ZVYilo8TAzPoI/tobN+59K5d5iFk4cJUdg8j/1OnCDqypat/LqbEBqah+BwepFs1GKZQAqSxe5GfTtZdOxcu4g3fugiUZB21lZAqeASgffryfmvW7GIY00bszlwYXAEEgA3LOOSqLdaCbm6ZSlXEXq9g7zuWyuWcnryvNpD3p+bipdyFqevDRBSszt3CWehe2C0AX46iHJ9NpaZIoqdxW9H3VQDAODGqL47DdZLsAYsMMiNWJ/Krevx016cnnoDALAt4z7Io4IMAGDAeRTTvjbIJVqsTHuYN845XtCMdvNjABhk6W5Hrv7+uPP/UkjVbAcAOPyxo6ZnQykjhMAfI4UtpOAIWdYAwMsSIaWMn7hmZ5uR6qMiwad8ZLGeooyqx/GQ7RnqKJLiYnvYaLkkZdDOWtD0XEVmwGoFQJqO6lXc6+pngwkKomxr/WZCWvLTTLzX0TNGFJpiATsbwzDoGWataDHqc3oG2Nqc/NjkpJvtjTOfwII+dm5apgE6gT5cscAwDLqayW9E2dKFs555nF4Ms9dUspRvtRUhQsTHA2VlZbjmmmvwxz/+EV7v3LbquSASHhEiojDaO4nxgSnIFTIs38Rf7F8pzrCkpbK2KKF0NrvNjcsX+gEAG7fHr98JBCicOU1qZDZtrog57+Q5MmfjmjLBGp8Tl3pAMwwWFWUgJ527mAtSNA43kP131XIjmN2+AI63sXU/Ndx7934LIUkrC3ORZYwsQjunptAxNQWFVIq9iyLXbPF6cHSIHOuWisjrdgX8ODBEjnVrSaQOykcF8e4wWZjfVlgT3s4wDN4cITa3m/JWcZ7qfzhxDhRDo0JfiFId92ny0ckPAQCb07fyktkuzRyAh3IgWZmFKhM3yAAgMdT106SHzdLke6CRx34azzA02qb+GQF6GkmKCpSlfHtBVcWrQZKSNHL1UxMI0s4550vYPymh8IFo+NlaIIVUWHVwBonKopNzyYuH8sHDKjzJSi5RmfASopKp4X5Oh91WAEBekomzfcBBthfqudv7bYSkFJm423tnyPbilGTO++Ly+THG1vaUpHHtZT0ThNSUZfJtZ72sZa0kmz82NmWHy+OHXCZFUXYMwsOGEZTGqc3pZVPXysrmDrvo7WJT1ioSC8YYG5iG00aS1BYykrqnaQgMwyA9N3lBmz2LECHi7wuNjY1YsWIFvv71ryMrKwtf+MIXcO7cuSs+nkh4RIiIQkjdWbq2DJo57CCJ4CwbJLB2x9yhA5z9TnSComgUl2UiNz+2bx8AGhsH4XL5YErWojJGwS/DMDh5liVFa8sE5xy5QMavWcXvKXOpaxhWpwemJDVWVnCfwB5v64U3EEReqhGVudx6gPeaWeWnikuE3mljFamSYhjVkfv9bk8HgjSNyrQMlKdEnmbvH+yAJxhAsT4ZNWmRhdbhsU7YA15kaQxYm14U3t5uH0W3YxxKqRx7siPJeDRD48AYqeu5NotrcxvxDKPT2Q4ppNiSfg1njGYonJsmFq8NabcK1uV02d+BPTAEtcyEpcl388ZnY8j2O1i9pyCVqLEk/QnIYpCBvwbkUj2UMvI+ugM9c84P3QsmqjloCAGW8CilfAUHAFxBQqp0Mi7hmfETUqORqaCVc+9PmPCoTZztIyHCo+VuH3SwgQF6rsLSZyPzi41R2y1kfkkKl4D0TZPtqUlamLTca+qdYElNJp+09LIKT2kO/7vcPRRSd1IFY+IdTi8m2B49pYVzE56SeSg8PR1XRng6m0jD4dLK3AVNUuts6AcAlC8vjD9RhAgR/9CoqqrC448/jpGRETzzzDMYHx/Hpk2bsHTpUjz++OMwm80JHU8kPCJERKHuXRJpvO7axGKj48Hl8KLpXC857o7E7Gx1h0ni2VzqDgDUsXa2jRsqYqazdfZOYnLKAbVKgZUCgQxOtw/nmklAwrZVfEL0wSVS+3NNTRmvBuFAI1Ferl1ewXkaPjBtRfPoBGQSCXYviZAohmHwdhuxs92wmEuE3uwkr/vmcu7rfr2XTXMrreKc441BYme7uaCaE1bwNqvubMuohFEZsbk1Wbsx6jVDI1NhS0akJw8QUXeWm2qRrOQuWjvsZ2ENTEIj06PaxCVDABCkvWicfhoAUJ3yABTS2GqeJzCIfusvAABlKf8RVlT+lqBVlACYH+GJKDzChMfPWtZiKzws4VFwbWgzPrYmRsl/4j/hsQIAJ4gCAIZdZHtuFOGZU+GJJjwhhSc5avsUITXFaXxrWpjwZHA/OwzDoGeUEB4hhadrkPwBLy8QJiohO1tmuiFmQhtNM+hjU9dKSucOIejtJISnJFHCc5kQnorqhbWddTWQ357yGpHwiBAhApDL5bjlllvw0ksv4b//+7/R09ODxx57DHl5efjkJz+JsbGxeR1HJDwiRMyCdcqBFraYf/2+mgU77qUTHQgGKOQWpyMvgV4XXo8fF8+w9rM5CA9NM6irI9e+cRNfmQkhFFawekURVCp+7UldQy+CFI2inBQU53IXZRQdsbPtiLKzubx+nAjZ2ZZz7XTvtxAitq6kAKm6COloHBvHkM0GrUKB7aWRfj3DDhvOj5N6nxvLIvU+424H6sb6AQC3FEeIo9nrxIkJcl03FUQCIbxUAPtHCRG6MW8V95rG6wAA12SshmZWzYiH8uDM9CkAwLaM7bz7c2b6LQDAypS94SL82WizvgQPNQWdPBsVhpt547PRM/NDMPDDpF6PLN3tcef+taBVkPfF7Z+/wkPPofAIEZ4gHYSHIkEDOnkU4fGH6nS4hMdLBWANkH2iCU9I4cmNsrQNOsn2Ah13eyzC0zvDEpsU7vYeM9lemsYlNUGKRv8UOVZplKVtyuaCw+ODVCJBoUANTzdLeMpi1OeE7WxxeuuMj1vh9QagUMiQFyfYACCNQ/u6WTVoUWKEJxRYUF61sNHRnWHCU7SgxxUhQsTfJy5cuICHH34Y2dnZePzxx/HYY4+hp6cHhw8fxsjICG666aZ5HUfs6CVCxCycO3gZNM2gdFk+sgoSSyyKh7Ns/c7aeag0s3H+VDf8viCyc5NRXJYZd25H+yimp53QapVYUVskOIdhGBxl46i3bRCu8QnZ2YTUnfruEcw43DBoVVi9iPtk91hbL3xBCoVpJizK4S7I3mXtbPui7WztRN3ZWVYKrTJCvt7qItvX5eQja1ZPlDd7W8EAWJORh/xZT+jfHmoCxTBYkZKHEn3kfTs60QJn0ItstQmrUkvC221+B05PkcS8a7O5drYz03Xw0V5kqbOxWM8NURj1dGPI3QqpRI7VKXt598dPOdBseR4AUJP6WciiIpRnY8ZTh2nPh5BAjrKU//ibqduJRkTh6Z1zrgSspS1GDU88S5ubcrHHkEAr4yarRQgPl9RMsnY2tUwBw6xYamfAB6ufjYWepfC4A36Y2VjqwlmWNm8wgFE2pa3YGJnPMExY4SmJIjy9rMJTEkV4hqatCFI0NEoFskxc4hays+Wnm6BS8P/8dg3NofCw8dFlxbGVm95QT52itJgqbwjDg9OkcahWiew50h9ng2EY9LKR1MWLFy6hzeXwYKSHBBaUL1+4dgAiRHwUcAf8kAeEmyh/VOf7OOHxxx/HM888g46ODuzbtw/PPfcc9u3bF+75VVxcjN/85jdYvDh+q44QRMIjQsQsnDlAFsELaWejaRoXTxCr19prYvfFEcLZ44QorN+2eM4F8RlWCVqzphTKGJ76wZEZDI7MQC6XYsPqUt64PxDE2aZ+AMDWlXzCc7SRPOXfWl0KhYxbY/BhEzn/7ig7W9+UBV2T01BIpdi1OHJOhmGwv5OoTddF2dne6yH366YoO9s7A8TmdlMJ1xb4zhCpu7qxgBv3HYqivi63ltPb5Zj5EoIMhTJdPi+soG7qOHmN6dt59/zSzH4AQKVhI/QKgRoM+3vw0w6YlMUo1u/mjYfAMAz6LY8DAHIMn/ibtLKFoJKTBa2fmtsvTTOkj40khnnAQxHLmlDPIoufEAudXM/rwzPpJeQiVWXibB92EwKRreEGCvQ7yfZkpRY6RYRc9drJcZJVGhhVEZWp20K2m1RqJKsjxGnS5YLdxyoyUWEGnZNsLU4693PQOUbqcEozU3gpiV0j7JhA/Y7T48PwhBVAbMLT2UvIQFkchaebDSEomUdPna42YgUpKU+scejEsCUcWFAwx4OYRNBZ3w8AyCxIhTFVH3+yCBF/Zax59teQav5yNZe05+qTyv6e8OSTT+LTn/40HnzwQWRlCSvQBQUFeOqpp+Z1PJHwiBDBIuAPov4oq8TsTqxPTjz0tY/BOu2EWqvEktr5+9JpmsYFNnFt7abYiWshnDtLnsCvWVsSc86pc4SwrKgqQJKW/5S9oWMEbm8AKUYtFhdxFzIMw+B4EznHlmruOfzBIOo6iBXlmqVcInW4g5xzdVEeDLP+ODRPTGDc4YRWocCmosh9GbLb0Dw1AalEgl3FESIw5LSiaXocUokE1xZECNKQy4IW6xikkGBPToQg2fxunJkihGp3Nvf9PDpJ6nq2Z67mbB/xDGPQPQCZRIY1Keu5r5H2otl2AgBQm7IH0WAYBp32NwEAi423x20yOuM5Coe/CVKJBgXGh2LO+9uAJOq/seGlrQAAtcwkOG4LkAW/QcFfsJt9xFqVruIv1Ec8ZCxPwx3rcxISVpzEPV63nVVKDNzt7VayfZEpavs02b44NZ1DnNon2eOnJEOtiCiQLp8fA2xoweIsrhLcNkKudXEu/3W0DbFjBfyxjv5JMAyQlapHsoHflNjnD4YtbUsqYqeidbIhBIvmYVHraCGx0osStKV1sYEFxYuyoVQt3DKilf19qhR4GCNChIiPFw4dOoSCggLewxiGYTA0NISCggIolUp86lOfmtfxRMIjQgSLljPd8Lh8MKXrUbaAdopLJ4laUb22NKE0o56OcVimndBolVi6Iv71zMy40MkWH69eE5vw1J0nC4oNa4QXFKcaSQ3OhuXFvKfTAxMWDJttUMhlWLeES9wu9IzA5fMjTa/F0jwuUfqwnZxzx2LuOQ91ke1biougkkfuy4E+QlLWZOchVTOrl84guY9rMvKRqo5s3z9CSOqa9EKkqiPKwZGJFlAMjXJ9Nop0kQXmmMeMDscApJBgczo3rODMNKnrWWZcDn1U4Xyb7RT8tAfJyiwUavnBE5PeRtj8/ZBLNHOqOwNsUEGu/hNQyuLXWfw9wUcR65lKZhQctwfIgt2g4NtF4xGeYZbw5Gq4RKXfRbbPfn8BoMvBWr+iCE+HJUR4uOdvn4kQntloZQlPZQZ3e+fkFBgA6bokpOm4alU7S3iW5PBJXfsgS3jyhQkPACwuFlZMuvsmQVE0ko1aZKQJqx8Mw6Cjk6g2FfOIiu5oHgEALEqwj04n23+nfNnCNgZtY3+flsT4fRIh4m8J5z71EAyGv1x0ut1uR/bX/+Mvdr6/NkpLSzE2NoaMDO7v5czMDIqLi0FRwrWisSASHhEiWJz/oAkAsGpHVUL2jrlQzwYJ1MbpiyOEcyxRWrGmBAoBv/9sXDhPlJey8kykpOgE59jsHjS3kwXOxhhPUOsaIoQnGieaydjK8jwkqbm1KUdbyfm3VpZwiNK00436IeL1374oivB0sxa4cq6d62Af2b6nmBuK8N4AsfftLeTa3/YPE5vb3lwuCTk0TuyJfHXnIgBguamCUwRPMzTOsmEF61M3Ihr1lkMAgBrTTkF7YaeNqDvF+p1QCli2QiDqTjOkEg3yjJ+JOe/vET7KCgBQzaHwGBNQeAJ0IGxpy9VyyUA/q/AUxVB4yvRRhCek8CRzz9E+Ta5rSRThaWdjTxenc7e3jbFEKJt7HIZh0DbC7hOl8Hh8AfSz6W3ChIfY1RYVClvR2lgis6QiO6a9dWrKAavFDalUgtI5EtoCgWA4oS1RwtMVSmhbtnAJbTRNo439HRMVHhF/D9AqlNAqYtdpLjSCf8Fz/S2AYRjB7U6nE2p14lZCkfCIEMEi1H9nza5lC3ZMr8eP5vOEKNRuTIzwnGeJ0uqNsRPXwnPZyOs1cZ6MnrnYSwIZitKRlcF/Aj80YcHguAUymRRrq/jWuxMhO9syLhliGAZHW8iT2W2VXHXpaGcvGJCFYfasZqP9Fgu6pqYhl0qxrSRyPLPbhfNj5OnxnpIIERp3O3DJTMjanoLIfRxyWdBsHYUUEuzKiRQuTvscuDhNrndnVuT9ZBgmbGfblsFNbWuzt8AasCJJloQqI7eGa9o3ikF3CySQYnkyP7nNS9nQ7zwCAKgwxk6M+UdWdwDAR4VCBK5C4VFzF+qjnikwYKCRqZA8S3VjGAZ9rMJTEq3wxLC0hRWe5FiWtijlh1V4lkQ9YWwbZ9WYLO5xzHYXZpxuyKQSVEQpPJ3DZjAMkGZMQpqRT4jbWYVnUVEMwtNFCM/iOM1EO1g7W3FxumAC42z0dU0gEKBgMGqRlUBgAU3T6GKVoYVUeAY7x+Gye6BOUqE4Rg8xESJE/OPj0UcfBQBIJBJ8+9vfhlYbcXRQFIWzZ8+ipqYm4eOKhEeECADjA1MY7ByDVCZF7bbEggXioeV8HwL+INKzTcibRxPAEGwWF9rZRcVchIeiaJy/MI/6nZCdLcbT0xOXyDFWLMqFLqq+x+H2or6bXM+mKi7h6RybwpjVAbVCjrXlXOvdh2z9zo5odaeLrU3Kz4dh1pOaQ/3dYABUp2ciRxdRX0J2tpXpucjSRha9sexsh8ebQYPBUmMecrURUtHjHMawZxJKqQIb0rjKT8jOtjplHRRS7mKxwfIBAKBUt0Jwsd5r3w+a8SNFVY5UVewkvoi6o/2HU3eCtA9BhhTVqqR8wkMzFOwBUugfT+HJiFJ4hsP1O5kcZcPid8Ee8EACCQpmKTyuoD8cSV1miBzL6vNgwkNCEyqMkffQ7HZhyuOGBEBFcmS7JxAINx1dEq3wjLNEKIrwhOp3itNToI5SZcP1OwLqjscbwMAYUX9iEZ52Nowgfv1O4na2iqU5CSUEjvZPwe30QqmSo7B84QIL2tj6nUUriiATaLoqQoSIjwfq60kvRIZh0NTUBKUyomwplUosX74cjz32WMLHFQmPCBEALh4mzSwrV5dCZ+QXDF8p6k8RlWbFxvKEFhX15/vAMAyKSjOQnin8tDyErs5xOOxeJCWpUBnjyWiQonGunihNsexsJ+sJ4dlcyx8/0zYIimZQnJWCvHQTZyzUe2ddeQE0s6Kl/cEgTvcOAgC2L+ISscM95Fy7yrnn+rCfLHqi7WyHhsh9vLaAq5J9MEriq/fkcknq4Qnyfs5WdwDg5BT5IV2TshRaeSSNy0/70WC9RF5HlJ2NYRg0244BAGqSd0AIPY73AADlhpvivs9DdtKQNFd/39+NusMwpFmoJE4IAwB4KGILk0oUgs1W7YEpMKAhlcihk5s4Yz7KB4ufLPjTVdxF9JCLLPRztVwi0OMkFrAcTTLUssjnrstOiEWaKgkpqsh3uXWGzM/TGaFXRgh9yxRLUozJ0MwKJmibNINmGKRptUifVafjD1LonGAtcFnca2odJudYnMsndK395HUI2tkGSGBBqjEJaSa+JdVm92BolJCvRXFS0drZqOj5BBa0sXU4idrZOhqJna20MndBiUnLWfIQRKzfESHi440jR4hb4sEHH8TPfvazBauTEgmPCBEAGk6ShfOKbYn1yZkLofqd5esTix1uYC1qtevm/uN/6VI/AKBmRWHMvhttnWNwuf0w6NVYJGCJcXv9aOwkT3yF6nfOtJEEtg1Li3hjpzrJ2MZF3LGLg6PwBIJI1yVxrD8Onw/1o+RJ9NbiyLm8wSBOjRCCdE1hhCC5An6cnSDbd+RHiNCMz43GGXLN27MiRMgR8KDB0k+On8klQmemSZ3WhjSuZa3N3gIf7UOKMhXFSVxyNurphi1ghkKqRrmem+oGAHb/EGZ8XZBAhiK9MCECSONOm/csAClyDJ+IOe9qwDCk/41EsnA1aN4gucdqefx+KzY/+RwYFPmCpG/C2w8ASFfl8xLshj1DYMDAqDDBoOD+cet2kgV2WVR8eKuNLNgXG7nXdZn9TFQlc7c3TJHP3PJUrvrRMMFuz+RubxwjBGV5Dnd7+7gZfoqCSaNGQQr3YUTjADlWdSFfYbncx46V8MeauglRqYphV2tqI6+pIC8FJoEEN4AovW1sM9BYDz5mo7mevF9La+afHAkArezvTSKJk3OBYRhcZvuDVcfoDyZChIiPF5555pkFPZ5IeER87EHTNBpPsIRny8IRnplJO3rbRiGRSFA7j1jp2Whg636Wr+KTj2jUXyILl9o4C5DzDf0AgJXVwqToYusQghSN3Awj8jNNnDGGYXCmjRCOdYu5ljW3z4/6frLI2rCIe/6T3eScG0sLOQvg0wODCNI0ipOTkW+KLBgvjI/AEwwiQ5vEKR6vG+tHgKZRoDOheFazyBMTxP622JiJLG1kkXxmqgsUQ6M4KR152ki/k1GPGUPuCcgkUqxM4b7P9RYSZFBjquUt1tvsxOpWrlsFhUDDzH7nYQBAtnZVzNoVABh1vggASNVsg1o+t+UoEfgDXXA4n4LT/RJUylpkpr28YI1MvUFCLNTy+PUaIcJjVBYJjocIT6aaPz7oJmP5Wv5nOEJ4uAXybSzhWWLgXleThXwel0URnsZpltikce99/QSZX5PBJRsNY2R+TXYUQRom85fnccMDaJrB5QGWJEURHovTg8FJK7muYv5739xNzrWsTJhUNrWR11q9JPZ70N9nhtvth1arRFFxfPusecKGiVErpFIJliRYhxMiPJUrixLaLx7GB6YwOTwDuUImBhaIEPExxq233oo//OEPMBgMuPXWW+POfe211xI6tkh4RHzs0dcyAvuMC5okFSpWLNxTy4tsylpZVS5MqcLJaUKYGLNibHgGUpkUy+Z4iurx+NHE9sSoXRmbHF1gCc/qmiLB8dOXyfi6ZUW8hXL/hAVjM3Yo5DLUlnMXRxd6hglRSjEgP5W72D/ZQxbAm8q4r+F4HznX5mLu9qODbNJbQTHnGo6Oku3X5JZwth8bJ+rZ1kyuenbSTJ4Ub8zgdl8+N01CKaqMZdDJI0/JaYbGZVsDAKDGtJKzD8MwaLOR5LZK4wYIod9BCE+RLra6QzN+TDjfAABk6++OOS8RMAwNj+8oHI7fw+M7Et7u9dXB66uDRr1pQc7jCZLPl1oeP5HL5u8HABiVwp/ZSZbwZAgQniE3+awUaLmE2up3wOyzQAIJr0Fsm42oHpVGrppxORbhYRWemrTIdoZh0DhJSMqKzChFaDREeKKI0DCZX5PHJS59kzNweH3QKOSoyOYSjiZW3SnKTIYxiZsuxDAMmthAgqpyYSJ8uZW81uo4yk1LC5mzpDInptIbnttAHmCUVGRBm8Qn8bHgtHsw0Else5W1RfPeby6E1J2K2iKoE7geESJE/GPBaDSG/84bjfHt/IlCJDwiPvZoOE5ijavWl0M+R/xzIrhwjKhGq7YsmmNm1PWw6s6iyhwk6eJHLzY2DCIQoJCVZUR+vnBNiNPlC0farhKwrzAMEyY866uLeON1LWRsZXkuNFHJTyE724YKrooz6XCiY2IKEgAbSiKLWIZhcKKf7LOlmHuuY4PkPNsKijnzj40QwrMtN/LkN0jTODlB6n22ZkdsbhRD4zRLeDalc+/7+RkScLA6hWtz63V2wxl0QCtLQrmeq8SNe3thCYxDLlGiTMclQwBRNSx+Ymcr0G3hjYdg8dQhSFuhlGUgRbM55rz5gGEYOF3Pw+78DQLBbnarBBr1bgA0PN5DsDt/v2CExxtIVOERJjxhhUdVxBsbDBMe7lhI3cnVpHNqrix+J8a8VgDAYkOEBNj9XvQ7STDCsuTI9nG3A+NuB6QSCapSIjUw/TYrrD4vlDIZpwfPpNOJEbsdEgDLognPEEuE8qMscKydbWl+FuRRhONyL6vgCNjZxqcdmLa5IJNJsaSIX5/j8wfR0UNIVnVl7Pegma3JqaqaW7FpZglPVYIPeDoaBsEwDLILUpEcoxfQleByHdurbGNiv5UiRIj4x8JsG5toaRMhYoHRwNrZahbQzkZRdLjh6Kqti+eYHXU9bP1OTZwGoiGcZ/tWrF5TEtPCVN9EAgfyc5JjxFFbMWq2QS6TYmUl/yn+KZbwbKgs4o3VdbCEJ8rOdqqHLKgqszOQkhRRU3pnLBix26GQybAmL3KuYYcNXZZpSCUSbMqLHKvLNoURlx0qmRzrsyLEqdEyDFvAC5NSg5qUyAKvzTYCa8ANnVyNalPkOO6gF802Qg7WpFRxrjWk7lQZqyGLqi1psxN1p0y/EkqZBtEI2dlytKuhksUurJx0vQsASNfunbP4fy44nL/HjO3bAACJRAd90j3Q6z4NhbwI/kAnPN5D8HgPIhAchEJ+dQ10GYaeVcMzP8JjErC0BWgfZvxk0R9taQvSQYx4yGK9IMrS1u0QtrO1supOYVIadIrIQ4FmK1F38rQmTmBBwxTZXmFK4/TNaJhklZW0TChlkfclVL9TkZYG3ayEoEmHE6M2lgjlcolQiPAsLxKo32EJz/ISvmUtZGcrL0iHWiBKuqt3AsEgaTiaHSfApJVVeCqXzoPwsPU7VTWJfT5aPgI7GxBReKoTjO4XIULEPy48Hg8YhgnHUg8MDOD1119HZWUldu+O3dw7FhausvUvhF/96lcoLi6GWq3GypUrceLEib/2JYn4OwYVpNB8mk1S25IYMYmHrqZhOG0e6AwaLKqef3M+hmHQeIEoPDXzqN8JEZ5Vq2OTo1D9zqoYdrazTWTxU12RA21UQ1FfIIhLXWQxGh1YMDJjQ7/ZAplUgrVl3IVTyM62sZS7gD3RT65ldW4utLMS3Y4Pke21mTkwqiIL2JC6sz6rAGp5ZP6JcaLubMwogWxWgf7pKUIy16SWQS6dtYC1diLIUMhRp/PSvpptpEHpsqjeOwDQaT8HAFhiELazDTpJeluhjt+bJwSGoTDtJpaz9KRrY86bL2zOXwMA9LrPID/7ElJM34dCXgQAUCoqoFZtBMDA7Xn/qs/lo8bAwA9AFrfuyB00w0fbAEhgUPAX0RPefjCgoZUZkRSV0DbiGQLFUNDKtEhVciO/O53kc1Sm536HWqyECEXX74RCLKLtbPVmtk4nlbv94jiZXxMVWHBphK3TyeGSmnpW3SnPSINOxf2uNLC1bNH1OwGKQgtb21MtUL9zuYu14JUJ39+WDjI+V8PRsTG2JmdJ/HAJh92D/m6STFe5PDHC08r+NlUuYGCBedQC84iFXPvKuR/yiBAh4uOBm266Cc899xwAwGq1Ys2aNfjJT36Cm266CU8++WTCx0uY8DzwwAM4fvx4widaCLz44ov42te+hm9961uor6/H5s2bsXfvXgwODv5VrkfE3z96m4fhcfmgM2pRtIDN7hpPEzWhel1pQtGtY8MWTJsdkMtlWDIHUTKb7RgZJguFmjhPahtbCWGprRaec6mNLB7XLOUvYi73jsEfpJBmTEJxFtcyd66btdDkZ0GvifjuGYbB2T5yzNl2NgA4M0i2byyK2j7Cbs/jbj89Tr7bm7KLONvPTvWT42dwF0iXZghBWpvGretpYtWdmmTuE2Rn0IlhT2jxvJQz5g7aMekjC+4SHZ8MeSkrZnyEYOUlCRMiAHD6O0AxDsgkOhhUNTHnzQcUNQOKIgvgZMM3IZUK2YpId2qZdP7NJGPB7iUx3jrlEkgksQ0BY24S+pCqWgS5lG/DHHQTO2GedhFv0d7pIE/3S3Tc6HaaodFiI+9npYFbyF5vYUM9krmf2fNT5P1alcb9HJ2dIO/x6kwuQTo7Sj7Da7K53/2zQ+z8PO78c/1k/qpC7vwpuwu9kzOQSIDaYu5Y68AEPL4ATElqlGSnIhqh79+KRcLKTGMLOefyOHa2BlaxKSvLRNIcNTCXL/SDYRjkF6UhNX3+tjS/L4BWNiBl2QJGR7ecIQ+cSpcVQDOHhVeECBEfH1y6dAmbNxML+CuvvIKsrCwMDAzgueeew89//vOEj5cw4XE4HNi9ezfKy8vxX//1XxgZGUn4pFeKxx9/HJ/5zGfw2c9+FkuWLMETTzyB/Pz8K2J6IkQAQDP7x7ZyTSmk0oUTPBvPRAhPIrh8kSzkKpbmQKWO3yk9tMgpr8iCLsZCwWb3oG+A9AwRWjAxDINL7SwhEkiAutDJLvwq+FHD57oJGVlTxiVmfdMWmJ0uKGQy1ORHnjZTNI1zQ+Rc6woi+zAMg9Oj5DzrciLbgzSN85Ps/MzIAtYTDKCJfZK/Ji2y4PVRATSxT/5rk7nqWJOVvM/LjNz+Pl3sYjtbncOLQx5yk9quNFUeT5UAgHF2kZ+sLIVGHrunjs13AQBgUK+4ajtbIEgIlkyWB6lArxsA8AfIa1Iorr4eInTtRvWquPPG3GRetlZ43qCL9EUqTFrKG+t0sgXrOu719rvG4Ay6oZGpUKaPfDZnv88rUyLvs5+mcGmaJe9pReHtzoAPTWxC29pZn6MptwtdFlLvs3bW587h86F5giggsz+nAHCOJfJri6O295Dti7LTYdRyv4sXOtjvV3kepFLud8jm8KB7iHw/Vyzmf/9omsFl9oHF8jhWtXr2t6BmHjU59WyDz/lYZmejvX4QAX8Qyen6hJooz4VQ/52l6xKL7hchQsQ/NtxuN/R68lDm4MGDuPXWWyGVSrFu3ToMDAwkfLyEV3ivvvoqRkZG8OUvfxkvv/wyioqKsHfvXrzyyisIBAIJX8B84ff7cfHiRZ5vb/fu3Th16pTgPj6fD3a7nfNPhIjZ+Cj+2Ab8wXB06/IEj1t/bv52tvAiJ04fjdBiqTAvFSaBhqp9I9OwOjxQK+WoLOH3ADnfQRZyqyq4iy2GYXCuhxx7dWnUU3B2UViTl83pNt9mNsPu8yFJqcTSzEhxdq/VArPbBaVMxknKap2ZgCPgg16hwpLkiA2tYWYIAYZGlsaA/KSIitFiG4KfDiJVpUdBUsQa5Qi40edi+5yYuO9Hp4PUb1Xo+eRggF2kF2j5i3QgssjPirHID8HuJcTIqIo/bz4IkRllDDJDUVOg6WkAEijk5YJzEoEtfO38wIYQGIbBmCdEePh9ihiGDis8BVpu/RTN0OhmSWf0e9BkYx9GGEo4tVUttmH46SBSlDoUJkUW3s2WUXioAJKVWpQZItsvTI6AYhjk64zI00VqYM6wJHtxajqS1ZH6rPPDI6AZBoUmE7L1EQVk2ulGl5kQpDWFUZ/5bvbBQBlflQ09NFi1iD9Wz5Kh4txUpAh8P/uHpmB3eKFRK1BRGrvhaCMbQjA/wkN+Y1bEscEKoYF9iLN8fdmCRZ4Ds36D14qER4QIERGUlZXhjTfewNDQEA4cOBBe/09OTl5RM9IreqSdmpqKf/qnf0J9fT3OnTuHsrIy3H///cjJycEjjzyCrq6uKzlsXExNTYGiKGRmcn/0MzMzMT4+LrjPD3/4QxiNxvC//Pz511KI+McHwzAfyR/bjstD8HkCMKYkobA89iJF6HrC9TvzePraUE8WOSviLHIaW8hiK9bT4Yuh/h4VuVBEWe88/gCa2e7w0Yu1wSkrJm1OyGVS1BRxawbOsraftcVR9qFBliDl5UI+S007PUpeR21mDtTyCEE6wzYbXZuZD9ms+WfNhOitSeMmw12aIfeuNpkbrd1q7wEDBnmaDKQouT+SXay6UK7jE4hBd2xVAgBGPecBADlxCA/DMPNWSeaDQIAoPAq5MOHxs+NyWQGkUuEGlfM+F2WDiz2eUR2b8NgDg3AHJyGVKJGhruaNT/oG4aWcUEjVyNZEN3UdhotyQSVV8RLamqzku1ll5H43Q7bF2hRufHnIzrY6rQDSWdvPsLbI9Vnc70mI8KzP4X62z7K2y7UF0XY2VsXJTENyEjfA4jxL/tdEkf9AkEJjDyHbqyv438HQ969WQN0BIna2pYtzII9hjR0ft2JszAqZTIplc/TUmZq0Y3hgClKpBNWriuLOjcblM0QZWr524exsLrsbfaGwhQW0yYkQIeLvH9/+9rfx2GOPoaioCGvXrsX69esBELVnxYoVCR/vqjw8Y2NjOHjwIA4ePAiZTIZ9+/ahpaUFlZWV+OlPf3o1h46J6CdLDMPEfNr0zW9+EzabLfxviPVlixABAGN9Zlgm7VAo5aiIUdB/JQjV7yxfl9iT0IGeSVimnVCpFHPW74yNWTExYYNMJkVVnEVOaMFUUyV8vFD9wEoBO9vlnlEEKRqZyTrkpXHToUIWnuWF2dDMCh9gGCZc57AuyvZzhv3+rYt68HBGwM4GRBaq67K49Rihhe2a9CLO9oshwpPCXVTHWji7g24Muck5KvTcwAo/5cGYhyzwhBQeR2AUzsAoJJAhU1PDGw/BGxyEnzJDAgX0ymUx580XgWB8hSc0vhB2NrvvEgAGGnkxlLK0mPNCSleGehnkAo1ZQ3a2fO0SSKMsfSE7W4muDHJphOyS+h1y/5eZoglP6H3mqqDnzP0A+J+LEHGebYsEZn3ucuf3OQ0T+SLu9nGrA4NTVkglEqws4X6PmvvH4Q0EkazTxK3fWblE+PvZ0Bx6YBH79yD04GPR4mxotXPX7wBA6aJs6A381MFY8Lr96Ggk50nUphsPred6SMx1cTpSs0wLdlwRIkT8/eP222/H4OAgLly4gP3794e379ix44o4RsKx1IFAAG+99RaeeeYZHDx4ENXV1XjkkUdw3333hb12L7zwAr74xS/ikUceSfiCYiEtLQ0ymYyn5kxOTvJUnxBUKhVUKrGJmQhhNLPqTkVtEZRz1MskgqazZKGW6MIg1H+nakUBlMr4X81Q/c7ixdnQaJSCc1xuH7r6SC2CUP8OhmFQH6rfWSxkxWELtAXqdyJPtLn79ZhnMO1yQy2Xo3pWbC9F0zjP1u/MfnLOMEw4sGD9rIUnFaN+x0sF0Gjh1+8E6CCarWRBtjJqIdwcXjhzLV49zi4wYJChyoRJyS3wH/Z0gAENkyIDRiW/XmHcfQkAkK5eCkWMWhoAsPnIPL1qGWQCxfyJIhAgr0UuF1b1fD6SKqdQXH28r9VLjhVP3QGAUTeZlyNgZwOAflcTAKBQgDiGLYU6LuEccI3BHnRBJVWiXBd5/0n9Tuh9jhBbbv1O5N44/LPrdyKfr0m3C92WGUgArM2OfB5tXi9aY9TvnIlRv3OeJf+VeRmc8A5glp2tIo/3HbLOUb/DMEw4cCR+/U4/OcY87GxNDWzoQIIpay0X+xAMUMjIMSG7gE/crhSinU2ECBHxkJWVhawsrt1+zZo1V3SshAlPdnY2aJrGPffcg3PnzqGmpoY3Z8+ePTCZTFd0QbGgVCqxcuVKHDp0CLfcckt4+6FDh3DTTTct6LlEfDzQyv6xXbJq4aJQgwEK7aGmfgl65EO9Marn0eOiuYm1osWJlW3vGgdNM8jKMCBDoEng0IQVFocHSoUMS0r4Dw0ae4kVZ0UZP72uoY+M1ZZwx+qHyPbqvCwoZ9nTeqZn4PT7oVUosCQjUo8z7LBhyuOGQirF8ozIj1q3bRqOgA9auYJTv9NmHUeAppCqSkLBrPqdbscEfHQQBoWGU9cRoAPoc7Ed6A1FnGsdcBOCWaLjE9OQupOjESYOFj+x7aaphe1uIXgC5Bw65cJEnisUJaB84/B4j0KtWguAxF67vQdhd/wOPv9pAIBWveuqzsMwDKbcBwEAyZrYDUwDtAuj7rMAgNykdbzxIO1Hj5MkvRVHJd0F6SBabc0A+Al5oSaxy0zcePFLM33w0UGkqwwomvU+X5wahJsKIE2VhHJD5PNSN9YPimFQrE9G7qz6neOD7MOF9EyYZtXvnOwfAAOgNDUFGTpdePuwxYb+aQtkEglWRyW0nWwn39u15fzv4ulW1ma3mD92tpmMleYJ1+/0DU5hxuKCSilHZYVwZDVNM7jA2mBX1BYJzpmNRvahyrJ5zJ2NSyeItXH5hvIFrd9pOMH239kg9t8RIUIEFy6XCz/60Y/w4YcfYnJyEjRNc8Z7e3sTOl7ChOenP/0p7rjjDqjVsZ9WJicno6+vL9FDz4lHH30U999/P1atWoX169fjt7/9LQYHB/HQQw8t+LlE/OOj6RT5I75sAf/Y9rSNwucNQGfUIL90/klGDMMk1P28JeTtr4odpR3q37F0kXBfjlDDw8VFmbz6nSBFh+t3lkd1h5+0OTFmJV3rl+VHNV8cJvvU5HH3qR9jO81nZXLqd+onyPwlqemcPjuNbKPIZalZnPqdJgtLqJJzOAuvNhu5H0sM3Cfp/a4xBBkKBnkSMlTcJLVBN1lwRteOAMCktx8Av0lmCFY/GRdqsjkbniB5wj9X0875Qp/0ILy+U3C4/g8G3afhdL8Kh/MZBKlQNL8MRv0XoVZd2ROwEJz+FniDQ5BKNEjVbIs5b8hVB4rxw6AoQLKSH5LQ46yHn/bAoEhDbhR57HJ2wEt7oZcbUJTEVeUuzBAb3OoULhE6NUUWyBvSKzjv87FxQkC3ZJZx6neOsn2ctuVxSe3RIfL3aWs+97yhPlFbi7nb69i+UsvzsmHQRP720TSD051kbNOiIs4+dpc33HB0Y1QPKwA4e5mca321cEBJqH9WTVU+lArhP9Xd3ROwWtzQaJSoqor/GZsct2FkcJrU76xMTOE5f4wocau3XL1VMgSXw4NOVp2qWcAeaCJEiPjHwGc/+1kcO3YM999/P7KzY/chmy8SJjz333//VZ3wanDXXXdhenoa3//+9zE2Noaqqiq89957KCxcuCZoIj4emBqzYKR3ElKpBFULmNDWFupEXluUUMz16PAMLNNOKBQyVFTGbxxos7kxNDRDzhOnd1BTO1sMPAfhqRJoeNg9OgWvPwidRoXiLK6FJdRRviwrFUlRjUobhtkGj1GEp2GU7FOTE7Wd7XQf3fixgbUh1aRxr/0yS3iWJUf1OrGzKo6Ru73bQQhHmZ5vywsRnnwt//djIkx4hBejNj/Z1zgH4fEGCBFTyxcmMEWruRYyWQ4oahRDY7UAggAAqTQZ+qT7oE96AHL51feTmnC+CQBI1WyDLE74Qb/jMACgSL9d8I9Rm50kaC4xbOCNX7Y2ACANX6Wzmsc6Ai602QkhWTOL8DAMgzozITwb07kL5GMTRK3dklXOmX9khCh123IiaitF0zgxRN6/bQXFnPkn+voBAJuLuJ+JUCPdTWXc7e2jk7C4PNCqFFhexP0Mn20fBM0wKMlOQXYKNyyDphmcbiLnWl9dBCFcYO1nq+PUF54/RwjditpCKBTxI89DgSjlS3Kg08+/fmdixIKhHvJbWbPx6pP/Qmiq6wRN0cgpzkBG3sLZ5ESIEPGPgffffx/vvvsuNm7cuCDHS5jw/LXx8MMP4+GHH/5rX4aIv3NcPknUndLqAiQZri7NajZaL/YDIIQnETSzhccVlblQquLXE7WwqUYFBakwClhhAICiaLS0s2pIjIaFTd1sVLMA4Qk9ma4qyuL1DgkRnuiO8naPF91mQsSWRxGeRlbhqcmOIjYT7PaMqO1mljilcbc3hQkPlwi12VhyZ+S+1i4nS3h0XMLhDDox4ycRw/kart2IogOY8hGiIqTwBGgX3EFS52FUxn/Y4g2GCM/CKDwSiRyGpAdhsf8ngCAU8goYdJ9DkvbWq05lC4GivZhwvQ4AyNTdGnOen3JhxH0GAFCo284bD9IBdNhJfc8SA7cxK8MwaLCS+qblJm7azkVLG2gwKNRmI0MdUeUGXVMYds9ALpFhTWpEsRlyWdDrmIJMIsHGWY1o2yyTmPA4oZbJsXZW8EXD5DhsPi8MShWHaHdNTWPC6YJaLsea/Mj7FaRonOkln6NNpUWcaz3dGelFpZBxCcep1n4AwPpK7j4A0D1kxozNDY1KgeoK/gMJnz8YDixYFSd2/sJ5QnhWz8M+G7Kz1ayeO/J+Ni6ytrPFKwqhj/F7cyVoOEFUI1HdESFChBCSk5ORkhK7x12i+LsjPCJELAQu17He8Y0LZ9FgGCbcf2dJokXB7NPcqhWxa3LCc5tDdrbYi+i+wSk4XT5oNUqUFvGtdW6vH92DpGB6mSDhYclSicBYDMJzeWQCAJCfbESqLrIwcvh86Joi5GI24fFTFJqnyD6zF56eYAAdVjM5xyyFx+73ot9JjjOb8HgpP3qd5DiV0QqPkyxIownPEKvupKsyoJVzF3Fm3zBoUFBLk2BQ8NPJbH5yTLUsGSpZ7F4AFO1GgCbXu1CEBwAM+i9AItVCIS+DWrV5QWsqAMDsfh9B2g61PA8pcep3hl0nQYftbPw6qD5XI3y0Czp5CvK13EXtkGcQ0/4pKKRKVBq4vXnOTpO6njWpXDvbSTNZIK9MKYZWHgkHOMra2VamFsCgjNjNjrB2to3ZhVDLIn/qjg2S7Zvzizj2yuOsurM2Pw+qWfVnl0fG4PD5YNSosTQnUh8EIGxn21DB/b4zDIMzbWRsfSX/t+A0a2dbVSlsV2tuH4HPH0RqchKKC4QT8jweP1pbCdFfOUfENMMwqGfJUaINRy8eJ7+VqxbQzgYADcdJY9+azSLhESFCBB8/+MEP8O1vfxvPPvsstNqrf9giEh4RH0tcriMKT/XGhavfmRy1YnrCDplcioo5YqWjEVJ4lsZ5mhtCSOFZujS2dSnUcHTpohzIZXxrXVvfBGiGQWaqHhkp/ECDy32E1EQTnkCQQuswIRfLo/rvNA6zak2UutM0PgEGQJ7RgHRdJNGsfdoMP0XBqFKj2DirgejMBCiGQbomCdnayLU1WwkJy09KRrIq8uPXaR8HxdBIVemRrooQkAAdwICLtd/po/oIxbGzhep3MtRFgmQiYmebS90h75NMoodCZow7NxFIJAoYdJ9esOPNBsMwGLX/CQCQpbsDEklsm1Sf80MAQJF+h+B9arXVAQCWGNZBIuF+BustpKFplWEZVLIIeQnQQVxgAwvWpXJjvE9MEsKzKYO7QD46RgjP1iyu3epYyM6WG1W/wwYWbC0o4h6frd/ZXMzdfrKbJTUlBZx6MrcvgEtseMf6KMLTP2HBhMUJpVwmGPpxhiU862LY2c6ztS2rVwh/BgESXBIM0sjINCAnJ1lwTgijQzOYmrBDoZChMoHfJoqiw/13ajct3G+lZdKO/jb2ocqmhSVSIkSI+MfAT37yE/T09CAzMxNFRUVQKLjul0uXLiV0PJHwiPjYYWbChtG+SUgkC1u/08GGDpQszoE6RlS0EOxWN0YGiRKwpDq+EkBRNLo62UL/OPU7rZ2sJW2JcP1OWy+riJRk8cbsLi+GzTayfyF3vHtiGr4gBYNGhcI0E2esZYwcc1kud5/mcXZ7VLRkyxQbmZ2eyVnUtcyQ+dWpWZzt7Tb2mk1R1+Qgr3WRnlvUOOIxI8hQSJJpeIEF416yT56Gf79n/GQsTSX8XoTsbDp5/FqrIG0HAChlCyfJf9Swek/D4W+EBEpk626POc8dnMKIiyTCFet28sb9lCdcv1Np5KpEDMPg7AwZq03mNmO9MNMKN+VFitKACn2EREz5HGiw9AMANqcvCW+3+704ayYE5prsyILc7HHhgpkQzmtmEZ5xpwOXzROQANg2K7DA7vXiLBubHh1YcLSTHH9TWRFn+5muQQQoCrnJBt53oa6ZTU4ry+X0qQIAm9ODxk5ybbHqd05fZK1q8ep3WMWmtjY2KQrhwilCCiuXFyT029TdPAyn3YMkvRplcR6wJIqLR0koRemyfJgEEiRFiBAh4uabb17Q44mER8THDm0XyEKhcEnOgtbvdLGe+/I5SEs0OlhbSm5BKgxzeOQHB6fh9Qag0SiRnx97Id3eRUhRpUB9AAB0DBDysLiIH0fdPkQW9HlpRhiSuGmM7SNkbEluBm+R1TZGbGiV2VwLXbuZbF+SEbV9mt2eyt0esrMtMnHtQ102cu4KA3d7v4vML9Zxt4+4yfxcLf9azV4ylq7i7gMAtgA5nlEhnLLnpawAALXMJDjOx8Jazj4qMAyDfusvAAA5+ruhlMdOGey2vwsGFDLU1TCp+DUhrfZT8NMepCizeY1bu51dmPKZoZKqUWPi9vg5ZibKz5b0Wk6QweHxZtBgUGXMR442omZ8ONaBAEOjwpCBUn3E+nVwqBM0w6A6NQt5s+KoD/aTcIParBxkJEVip4/19SNI0yhNTUFxSuT4o1Y7WscnIZVIcE1FFBFqZRWkpSW8z9fxJkJ4tizj28dON/aDohmU5qUiN8PEGx+dsKJvYAoyqQTrVsa2n4UCC9asnbvf1/lT5HWv3pjYA55LbK1jzYYyyOTxQxESwflDxLa4etfVN+MVIULEPya+853vLOjx5h8jJULEPwhaz5GFSuXqhesYDgCdl8kT4oplidnZOlmL2qJ5PEHt7CDqQ3l5JmQCVjUAcDi9GBwh4QGLyoSb8razDUkXF/EX/CHCs7iAP9Y6zI7lcscsbg/G7A4ylsldKLeFCE961HaW8CyOJjyWEOHh1i50Ocj2MgN3fp+TbC+KIjzDHpa4afivY9JHCJ8Q4bEHSG1TLMLjo4hyo1pAm9rfAqze07D7LkICJfKNn4s5j2FodNneAgBUGIV7oDVYDgEAlpv4drcz0ycBACuTV3HsbO6gJ1y/sy2Dq/wcGrsMANiVXc3Z/v4wUQr25C7hbN8/QOpOri3g2qX29xKlY08x1/52sIsQgt3lXEJwuINNQcvPRkpS5GEETTM41kpIzbal3N8Rh9uLhm7ynd60jE8GTzWS/TbWCJOZU+zvU3VlHvQ64fYP4+NWDLIR0yvn6Nvl9fjDCW2rE7TwXjpJ7tdC2tmoIIWLh8n7tmanSHhEiBARG1arFb///e/xzW9+EzMzZF1z6dIljIyMJHwsUeER8bFD23myoFiSYGPQeKBpGl3NIcKToMKTCOFh7WzlFXwrWvh43WROTpYRJgEFy+nxYXDcQq61UIDwDLKkJl9gbDREeKLUmnFCOgqSjdCpI4tYXzCI3mnyIzVb4WEYJqzwzCY8DMOg00oIx6LkyHaaYdBjJ/PL9dxz97vINRUncbePsIQnN4rw+Gk/rAHy+uMpPEKBBQDgS1jh+dtHtLqjkgsTZQAYdZ+DMzgGpVQvmM427RvBoLsVEkixPHkHZ8xP+3HBch4AsC6Va3U7Pd0EPx1AniaDEzIx4bGi0ToACSTYkRUJOLD7vTg1SQjJ3tzK8Harz4PT48ReurcwQngsXg/OjhIVdjbh8QWDON5LCMGusmjCQ34rti/ikpqmoXHMON3Qq1VYGdV891TrAII0jeKsFOSnmzhjFE2H46hjEZ66c4R8bVgT+4FMSN2pXJoLXQxSFMLli/3w+4JIzzSisGT+vcHcTi/a2FqiFQtY69h2oRdOmxv65CQsWplYYpwIEX9LcPsDkPsDf9HzfZxw+fJl7Ny5E0ajEf39/fjc5z6HlJQUvP766xgYGMBzzz2X0PFEwiPiYwW/L4AuNhFtIRWekb4peFw+qNQKFMRQVYTAMEyE8MRpIhpCB6vwLFok3HkdANpZwrNYIH0NALoGyYI+I0Un2OE9pPAsiiI8FE2jY5SQkcoohaeNJTyLs7gLqq6paVAMg2SNGpmzOtePuRyw+32QS6UoTY5Y80ZcdjgCPsglUpQYIr05Rt02uKkAFBIpCnSR+a6gDxNeUm8UrfDMtrTNxpSPXKtaqoZOzq0fYBgmovAoY1jaaHK+eAltf2+Yr7oDAJ020qOn1HAt5FIVb7zB8gEZ19XCoIjq4WSth4dyI0WZigo9V305OnkBAFF3ZqtCH4w3AQBqkguRoY6oaiE7W7khHaWzVL9DQ10IMjQWm9JRbIh8Vj7o7wHFMFicmo5Coym8/fTgIFyBADJ1OlRlRb67do8X5/rJQ4wdi6OCD1oIEdq4uJAXR32iiU2BE1B3WrrHYXd6YUhSCcbBO10+NLBNhTesjm0/O3eWtbPFIUXhuXVEpVm9qTyhRL/LZ3tBBWlkF6Qiu2Dh+uSc/4CoeCuvWRpTpRYh4u8BG578DaTq+A8cFhK01/sXO9ffAh599FE88MAD+J//+R/o9ZG/1Xv37sW9996b8PHEXxsRHyv0NA0h4A/CmKpDTgn/6f6VoquJPDkurcxJyOs+OW6DdcYFmUyK0jiqDUACC3q62TqWRbHntrGBBUtiHC9kZ1skUL/j8voxMEnUj8X53AX/wJQVHn8AGoUchencVKi2MXLMyuwoIsTa2Ranp3MDCFh1p8yUAtWsyOBOtn6nxJgC5ayFZLedVXH0aVBII9sH2PqdFKUOBkWkmSLDMGFLW7TCY/ZF6neiF4AeyoEg4wcA6OXCi7yQwqP6B1F4iLrzcwBzqzvuoBlDLmJJKzfw7Ww0Q6HRegQAsCKZH2Zwepokt61L3cCp0bH47WiwEBva1gxuXc/BGHa2/SMkze3aWeoOAOwfZO1shVxCdaCPLPyvjWFn21lWCumsz8PxbrauJy0FRancz/vRFkI4tlVyCQdF06hr6QcAbBao36lrJPutXVYkmJ549lIfKIpGQd7/z955h8dRnV38t1W9d8nq7r333gsY02voHRJISEICqXwQ0kPooToEMNXGNraxjXvvcpet3nvblbbvzvfH7Go1ml0VECXOnOfRY5h7Z3Z2NLu6Z855zxtNqp/kNbvdyXF3/P3ESV2r1IIgcNRNeCb2smnoCXeSZV/a2QCOfCkS2IlK/Y4CBQq6wJEjR7jvvvtk21NSUqiuru718RSFR8H/FC4cE60rg8fJC42/DvLOiCpN/y564/jczx3Nmtk/oduGo6WlDdhsDoKD9aSk+A8suFAg1qcM6u+b8FwoFseHZMoXtvmV9QgCxEaEEBMeIhm7WOm2lCXFSuJ5AS7WiqrIwASpDexindue1ql+52KjmEo3MFo6P79F3D4gQrq9yN1/JytMur2sTdyeHiLdbnJaaHWYAEgOko412USLXUyA3LLW6hDJXpAmDK3a9+/D7hKPq1OH+Bz3QK0S1Q+Hq7XLed816k2bMViPo1YFdKvunG78jzusYBRRAfLFdq7hIK2ORoI1EQwMmyAZa7A2cLZFJC+TY6Sds7fXHMGFwKCwdJKDvPdKUWst5w0VaFRq5iZ47WyN1jb21ogqS0c7W5PFzO5K8TO+tAPhabFa2F1aDMDiLO/C3+50stVNeBZ0qt/ZfE4kCp3VnaLaRvJrGtCq1UwfnCEZO5FfQUubhfDgAEZlyQND9hwXz3nqKN9Wrj0Hxdec1oX6nHOiBIvFTkxMKP27UZNLCuuoqmhCp9P0quGoIAgc2SnGgI+d0XeEp6asgcIz5WLt0dyh3e+gQMH3GPsfuI/w8G9P6TcYDCT95slv7fW+awQGBmIwGGTbL1y4QFxcz+25HiiER8H/FC7mFAMwcExGnx63KFckLtldREX7QsEF8SlF9uCu1R2AwgJRmcjKiket9k3WjK0WauvF8ID+PgIJwGtpG5gm/8IorBQJRP9kubpRVCsShexE6ZjT5aK4QSQK/eOkY0VN4vbsTt2Si1vE7ZmR0qfYJcZmADLCpdsrTKKNLDUkUrK92iLOTwySzm+wifNDNEEEaqS2q1aHeH3CtPI4XJtLtAzo1UGyMQ9UeBQml985AEE6MVbZ7qrH4TSg/R5a4JwuMwWNfwQgNfzuLtUdo72Ciy2fATA65i6fcw42iHa3cdGL0XQijLvrtiMgMDhsKImBXjuXIAh8USXGVC9KnCrZZ325mNo2LW4Q0QFeS+T6sjM4BBfDI5MldrbPS85jd7kYEhXPwEjv9k0FF7G5nAyMimFQB5K9r6SEJrOFmOBgJqd564ZaLVZ2ueOolw7vpBSdFJWPSQPSiAiW2lm+PC4Sltmj+ssUnNKqJgrKG9Bo1EwfIyeLVqudA0dFQjRrqv/eNHvdyWlTp3VvUdu3XVTBxkzKJihYbj/0h7KCWqpKG9DqNIyZ2jtlqCsc2JQDwLBJ/YmIUeKoFfx3I1ivI1jf9YPKvoTjW3yt7wOuuOIKnnrqKT766CMAVCoVpaWl/OIXv+Dqq6/u9fEUS5uC/yl46ncG9KDBZ08hCAIFbqUma7D/2hpfKHTHR3dnZwMoKnLHL3dReFxQLM5JjI8gNES+wLE7nBRXisSlvy/CUy2OZSXJCU9BjXssXkpeKpsNWB1O9BoNKZHSRX2hO1WlY9QvQGGzm/BESLeXGsXt6aGRku3lbeL2lGDp9lp3/U5CoDQxrckqPhWK0stJRqtDVFw61+8A2NsJj//FoaeJpiB0TXi06jD0GpF0ttkLupz7XaGk5WWszkoCNMmkRtzb5dychtdx4SA5eCJJweNl4xWmi5SbclGrtEyIXioZs7vs7K3fBcDseGmQwanmPCotdQRpApgZP7Z9u8PlZGOl2FhueT/p631WchKAK9OlNrc1hWL611VZ0ijsz/LOA3DFwKESkrD+vGh/WzpoINoOquW2CwXYnE6yYqMZ1Em19BCexaOlyofT5WL7CZHwLBgrJwk7j4lj44emyuLeAY6eLMFssRMXE8aQAb6/D1wugf1uq9m0HgQJ7Nshvu/pc4d0M1OKg9tEojR6Sn+CfHyPfFXs33ACgClLR/fZMRUoUHBp4q9//St1dXXEx8djNpuZNWsW/fv3JywsjGeeeabXx1MUHgX/MzAZLZTni3auAaP6jvBUlTbQ2mJGq9OQ3gPi0hGFboUnq4sQgva5HRQef8h31+dkZ/gmRcWVjTicLkKDA0j08YS1wK3wZPskPG5bWYJ0rLBeJCMZMVESq5vV4aC8RSQeWZ0Ij0fhyYjwrfCkhflWePp1VnjM4vzOhKfRrfBEd0F4QrShsjGbywqATu2/EFXtVnhcOP3O8SBYl43NWYvJXkBE4Jhu53+baDYfoqzldQD6Rz+BpgtVq9GaR6FRjJoeG/OAzzmHGsSo6uERMwjVSX9/x5oOY3QYidRFMSpSeh2+qBbVnTnx4wnqoMbtqcul0dZGTEAYU2O9i/vclhrOtVSjU6lZ1s9rcys2NHG8rgK1SsUVmV7CU9VqbE9nu2LA4PbtZrudL912tsuHeLcDbDwjkoqlwwdKCFJBdQP51Q1oNWrmdIqjPllQSb3BRFhQABMHp8muz84j4mvNHu9bMdl7SByfMbm/X+Xm/PkKGhvbCAkJYPSYrr/DqiuaKLhQjVqtYvJM/4qRLxxyK0OT+tB2Zmhs5cwBkfRNXfb9+iwoUKDg+4fw8HD27t3Ljh07OHbsGC6Xi7FjxzJ/vrw+tCdQCI+C/xkUnC5FEATiUqKIiu87e9HFU57AghR0+p5/pAwtJmqrxYV5Vg+S3QoLe0B43ApPfz+Ex2Nn658a63NRVVjlJjWdLG0Op4viOrc9LUGq8BTUu61ucdLtpc0tuASBEL2euBBvvUub3UatqQ2QWtocLhcVbeL1SA+LbN8uCALlpmZArvB4EtoSg6TbG20i0YoOkPfKaetC4XEI3ROenio8IBKeZssBTN8zhcfmbOR8/WOAi8TQq4kNWdjl/OP1rwICGaHziAmUL56bbTWca/EEEsjDDHbWbgdgZtwcNCpNh/2M7K8X1ZrFSb7tbEuTx6DtEFThUXfmJA0kKsCbMrimUEz/mpaYQXywl8yuyzuPAExM6ke/MO/9sL2gkDa7nX4R4YxJ9j5waDKZ2VcgKsFLh/m2s00dmN6FnS0bXafgkpoGI2cLq1GpYNZYeX2O0+livzsuf/pE/+lse/e47XSTstHpug5H8ag7w8ekExHVdb1ZR7Q0tpF7Qnz/E3upDHWFYzvO4XIJZAxNITHNd+S7AgUKFIDY6mPlypWsXr2a4uJiVCoVmZmZJCYmIgjCV6rBVixtCv5ncNFjZ+tDdQe8hGfgyN41HC28KKpNiSlRhIR1HW3Z0mKirk6sPcnI9L9YKHQTHn8KT36ZO3jAh53NaLZS2yySgaxEKXkpb2zB4XQRpNOS1Mm2VuQmPJmx0qf6RW47W1Z0lOTLqbilGYDIgEAiArzvu7LNgFMQ0Ks1JAR7yUiTzYzJISan+SM8vVN4xOsY6lPh6YGlrV3hcfid40GwTlzcfp8IjyC4uFD/ODZnLcG6bPpH/7rL+dXmE1SYDqBCw5gYeWIOwL76T3HhJDNkFIlB0vqUUlMJhW35aFQaZsTNkoxtqzmMQ3AyMCyN7A69d+osBvbXiXazy1O8Nje7y8n6MjHl68r0UR3ek+C1s2X7sbMNkC7ePz8vFuVfNniwNAb7fD4Ol4shiXFkdSDxgiD4tbO5XALb3Ha2eT7sbLuOierNyAEpxETKyce5i1U0tZgIDQlg9HDf3yOCILDPXb8zvQdBAvu2fzU725Fd53G5BLKGJBPvJynuq+DYDvH3M37usG5mKlCg4H8ZgiCwfPly7r77bioqKhgxYgTDhg2jpKSE22+/nSuvvPIrHVdReBT8zyD/pEh4+vcx4WlvODqydwltRe76nawB3as7njjqpORIv40GnU4XhaViKpo/wlNQ5h7vJydNHnUnPjKUsE5Prwvd9TsZ8dGywIQit6UtM6ZTMEFTs7g9qlOdjpvwdOyFAlDWKm5PDYuUxANXue1ssQEhkghrq9NOi11MTIvvRHia7SJx81XD0+YU1aUQrXzh6XCJjd20Kr1szAONSiwcdbpsfud4EKIXF79G62kEwYFK9d1/5ZY0v0CjeRdqVQBD4p5Do5b3YvLAJTg5Wic2JB0QsZxwvfweb7JVc8Lde2dG/PWy8W01mwEYGzWeCF1k+3an4GJDlRhx3TmsYF35UVwIjIxMk/RX2lWdR721jeiAYGYkeJWQw7VllLY2E6zVsSjVSwbON9RxvqEOnVrNsmzv9iazmZ1FxQBcPkSq4qw/LRKhJcOkpOJiVT2FtY3oNBpZHHVOQQV1LW2EBuqZ7MPOtu2wSFTmjPet3njS2SaPy0LrJ9a+sLCOCnfi2oSJXcdRN9QZOOd+EDNldu8Iz4GtIjGZNK/v7Gwul4tj28XjjlMIjwIFCrrAypUr2b17N9u2bWPOnDmSse3bt7NixQreeecdbr311l4dV1F4FPzPoOicSEyyR/ROiekKLpeLgnNfLaGt1B1CkJHdfT8gT2BBV3a2mnoDNpsDnVZDUmKkzzklVW5ykiKv0SmtcdfVJMif6pY3ulPSYuQWsfJmcSwtWjpWaRRtZSkRUtJR1SYqLP3CpNtrTCJJSQySKi8NVpGgxAZKtxvtZgDUqAjVShUZs1NUaoI0cqXG5baiaXyQD617m1Pwr94EaUWyaHLU+Z3jQXjAaLTqSOyuBposB7qd/02jtm0DJS0vATAg5veE6ruu7cg3rKfBmotOHcroaN/JbDtq3sMlOMgMGUVGyHDJWK2lhkMN4vtekLBYMnaw4TQ1lgbCtMHM7tB7x+FysrrsMADXpE2W7LOqUGxOenX6aEk/plUXRZvb8oyhBOu8ZPXD8+4ePhn9iQz01iitP5+L3elkaHy8JDK9vKmFw8XlqIDLR0qJwtqjYl3L7GFZhAVJ76sNh0U1Ze6YAeh10vuqqt5AzoUKVCqYO0muzAiCwI59opo1e6p/5WaHp65mcjbB3SSu7fnyHIIgMGRkKvGJ8s+sP5haLRzdJRK+6Yv6rk9OXk4JTbUGgkMDGT6571LfFChQcOlh1apVPPHEEzKyAzB37lx+8Ytf8N577/X6uArhUfA/AZvVTplHURnWOyWmK9SUN2Fus6LVaUjtZSPTkkJxwZya2X2efLHbqpbZhZ2ttFxUYfqlRPlsamix2qluEElIepKc1JTUNotjvghPg5vwxEZKttscTmoMIlHpnNBWaRCJTUqnPgXVreL2hBBpDU2tWTxOx/oLEHuuAMQESBUZg0MkPKG6QEkTSwCLU1RfAtVypcZDeFTIPcA6t5XN7g4v8IUQd3Rzm6P7xmdqlZ74kGUA1LSu7Xb+Nwmj9TQX6n8BQL/wu0gMvarL+RZni7t2B8bE3E2QVt77qcpcwJkWMX1tfuLtsvENVetw4WJ4xCgyQryqhCAIfFomqkJLkqZLosO315yhzmogWh/KvMQOoQStDeytLUQFXJ/pJUiNFhMbS8RF+o0DR3vP32Fn9QWRJFw3RLp4/+S0qDZcM0KqNqw7JRKXyZmpJEV470+H08XGE+JrLB8nJUJWu4Ot7gS2ZZPkasrWg+J+Ywb3IyFaXjd29kIlNXUGggJ1TBrnW7kRBKGd8MztQZCAp35n5vzeqTSHd5zHZnWQkhFLZi8TJ7vCwc0i8Rw7d2iv6hwVKFDwv4dTp06xePFiv+NLlizh5MmTvT6uQngU/E+g7GI1ToeL0IhgYvvQl17ojqPOGJiItpsi4o4QBKFd4UnvImbaA4/Ck+HHqgZewpPupylpaXUzggDhoYFEhskTuUprRYUnLV5+fcoamgHo10nFqTYYEYBArZaYEKk1qspNeJLCpYu86jaR2CSFSIlNO+HppPA02kTbWscCdQCjXVRxwnXy92L1EB5fCo+7f05nkgQ9IzyhOjGJr81R43dORySEiEX89aatOF1tPdqnr2F11HCm9gFcgpXooFlkRf20231yGl7D6jIQqc9iUIRvcvRl9UoAhkfMIilIavOqsVRzsEEMMlievEIydqYlnwvGEnQqLctTZrZvFwSBVcXiPlelTkSn9i6O33erOzMT+pMa4r1HPy04jc3lZHh0AiNjvCmJmwvzMdispISGMaOf18Z6vraOc7W16DQaSTqbIAisPSkShRWjpUThYF4pDUYTUSFBTOvUbHTP6UJazVYSo8IYN0D+MGXzfpHwLJ7q21q2Y6+o7kyf1J8AP2Tg/PlKqqtbCArSM2my/1ADgJamNs64Qwem9tLOtnujuIiYsXRUnzZmPrRZPO7kRaO6malAgYL/dTQ2NpKQ4N/qn5CQQJO7x19voBAeBf8T8NjZMoem9Okf8vb+O0PkXdW7QktTG8YWMyqVin7pXScWCYJAcZFYe5PZhRpUUiHW4KT1k9vVAErdPXbSE6N8XoMSt6WtK4WnXydLW3mTuD0lMlx2zAp3h+TkTtY1D+FJDO2s8IhkIC5IquR4FJ5ofSeFx21pC9PKCY/F5SE8coVHEATAt8Kj9RAeoXuFp9XevcIDEBYwiiBtBi7BTL1pa4/26UvYnA2cqb3PHVLQnyFx/0Cl6pqcN1gucMHdZHRS3GOofdj/CownKGo7iUalZU7CzbLxjVXrEBAY0UndAfjYre4sSJwsqbM63VzK2ZZy9GqtxM7W5rDxaXEOALdkT2zfLggC718Ut980cIzkHvzAbWe7dvAISVz6p2fENLd52VlEBXnvnRNlVZQ0NhOs0zF/sJRUfH5cJEKLRw9Cp5Feu42H3TU/EwfL6tvyy+rIL6tHp9UwZ4LcyuVyCezcLxKeudMHy8Y92O7uizN12gACA7tuPnhwz0UxdGBgIokpPX+4I9rZxHOZsWRkN7N7jrqKRgrPlKNSqZgwf3j3OyhQoOB/Gk6nE63WvxKs0WhwOLoPDeoMRVtW8D+BorNuwuMnAemrovDcVyM8HjtbYkoUAd0sYGprDJjNNrRaNSn9fKs34FV40vwoPJ76nbQk+bjLJVDmtrR1VnicLhcVjSJ56azwVDS763Q62dmMVisGq0ga5AqPW/npZGmr86fwWEWFJ0am8IiEx5fCY3GKrx3gy9LWlcKj6oGlrZcKj0qlIj50OSXNz1PTupaE0BU92q8vYLaXcKrmLiyOUnTqaIbHv4pWLU+n6winy8remv9DjKGeT2KwvGeKILjYVrMSgPHRS4nSS/tPieqO2F/n8mRpok5BaznHms6jRsVV/eZKxt4vFkMMFiePJjqgQ7R06SlaHVYyQqOZnuBVkg5Ul1BkbCJUp2d5plfNKG5p4kBlGSrg2sHeRbbN6WTtOZG8dLazrT0pkoqFQwcQEuC9b0xWG9tPiylrl42VkpKWNgt7zxQBsHSinLB41J2pozJ8Nhs9k1tBXUMroSEBTBiTIRsHMYxk1053jVAP7Gz73Xa2aXP8EyhfOLT9PHabg5TMuD61sx1y29mGTMgiwkfvLwUKFCjoCEEQuP322wkI8F2raLX6//vcFRTCo+B/Au0Kz5DeBQt0e9xckfD0doFQ6iY8aV3U5LS/htvO1q9fdJe9N8oquiY8pVVuhcdH/U5tcysWuwOtWk1yjJS81La0Ync60WrUJEVJFyz+CE+VUSQ14QEBhOq9i0dBENoVnoROlrY6vwqPSHiiO9XwGDvU8HSG1Z22FtBLhcdjafPEU/tCqNZLeFyCw6f60RkJISLhabLsp6b1s2+F9DSZ93Ou7lEcrmYCtf0YkfAWQTp5glhnHK1/iWZbIYGaKCbGPepzzsnmHVRbighQBzMj7jrZ+PrKNQgIjIwYTUZIpmTsw9ItAEyPG0NSkPf+L2trYGeNSDpuTPemtrkEgf8UiCEGN2VNkCT4/efCCQBWZA4jVOf947jqnLjInpWWSUoHhXFbfgFNZgvxISFMz8ho326xO9h0VkxSWzFKagP78nQ+ZruDtNhIRqRJid2Xxy/icLoYkBJLdrL0s+x0udh8QCQ8i/zY2bbtcQcETOovCzvw4OyZ8vZmo+PGZ/qc44GpzcrxQ2IE+tQ5vbSzbcgBRHWnL1Xwg24726RFfacaKVCg4NLFbbfd1u2c3ia0gUJ4FPyPoPRCFQDpvVRiuoKp1UJtZTMAmYN6R3jKikWLWmpG94Sn3KPcdGF9M5ltNDaLxKCfnxqlilq3LS0hUjZW5VZwEqPDZIEH1c0ieUmMDJNYgwDqWkWSkhDeKVmtTTyXuFApSTE57NicTgBig6SKjcEmPrWJDJAqNiZ3PU6IVkpe7C7xOHq1XCHrarkWoAnA5GzD6kPFCdOJZLHV0YTTZUfj49gh2gT06jBsLiON1jxiA7tfWAbp0kgJu40K47/JrX8c4BsjPYIgUGF8h4LGPwJOwvQjGB7/KnptD2rFjF+S2/IJANMSnvAZVGBxtrLNXbszPe5agrVSslvcVsThxoOoULE8RVr7U9Bazr76HFSouD5N2ux0ZeFOXAhMjR1IdpiXWOysvkiBsZ5QbQBXdei9U2ZsZnOZSFJ+MMjbq8dst/PhebFXz01DpTUj7+WIi++rRwxD2+Fe3nT2AgaLlZTIcCZmSFXg1YdFC9zl44bIiMD6gyJB8xVWcPRsGTUNRsKCA5g2Wk5UbHYH2/aIasz8mf7vIU9YwbTpA7ttNnpw1wUxdCAthsweNDP2oNVg5uhu0c4267LRPd6vOxib2jixS3yPU5f23XEVKFBw6eLtt9/+Ro6r1PAouOTRZjRTX9UMQNrAvrNqlLlVmqjYUMIi/fcy8YXSYo/C0/0itMKTvtaFna2qRiQzYaGBhIb4loGr6t01NbHy3jQdCU9n1LS4FZkIuRWqzuiOjO5EbBrNovoSEyy9Lk0WcbteoyGwk0e31S4SkFCdlNhYnR61Rko+nO3x0nJ6o3HXqDgFp2wsWCOek8lpko2FaCLdtjaBZrvv2GmVSk18kPi0utZ8yuccX8iO/iVJYTcCArn1j1PT+lmP9+0pXC4rF+p/QUHjM4CThJAVjE58v0dkp8VWwv6aPwIwIupW+oVM8zlvZ+0q2pwtxAb0Y3LMcsmYIAh8UvYBAJNippAWLO159W7xRgBmxI0hI8T78KHK3MTGSlGtuTNbanN746JojbshaxxhHdS8t3OP4hIEZiZnMijK+/7W5p2n2WqhX1g489K9tUP5DQ0cLC1DrVJx4yip2vDhUZEgXTduhKQOp7iuiWOFFahVKlZMkFrgiqobOVVYhUatYulEOWHZsEdMgls4ZTCBejlx3n+kAIPRQlxMKONG+u4N5nA42eWOie6JnW3HZvF9zF40vFcqzaFt53DYnaT1TyBjYGL3O/QQBzbl4HS4yBiaQuqAvvvuVaBAgYLeQiE8Ci55lLvjqKPiwwmN6B0x6Qql+WINR1ovnqR6UOYOIehJJHV5uVh706+f/wJkD+FJTvDdc8Nis1PfLJKT5Dj5nOpGd11NtJwM1TR7CI+cDHkUnvgwKeFpMLltaEFStabZIlrFIgMCJQsyu8uJxSkWIYZ3sqiZ3dsDNVKC5HJb0zQ+anE82xwu/4TH7JATHpVKRaRe/H022/zX6CQEispBpemw3znyY6sZEP3bb4z0NFuOcKL6Rmra1gBqsqOeYFDsn1Cru+7ZAuBwWdhZ9SQOwURC0BhGx9ztc16VuYAjDRsAWJx0r0wBO9WSw8XWXLQqHVckXyMZu2Ao4XDjGdSouDl9iWTsncLdOAUXE2KyGRnltd0dbyjjWEMZOrWGW7MntW832Cx8mCeSzbuGTGjfLggCK08fB+C24WMkiuT7bnVnXnYWyR2i0i/U1JNTXoVWreaq0VJSs/qQqO5MH5xBYqT0/l9/QCQ0U4dlEBshvf/bzDZ2HhPrfpbN8E1UvnA34lw4exgaHzHyAMePF9PSYiYyMpix4zJ8zvHA0GLi2AHxNWct7F04wD43UZq2uO967wDsXism681YPq6bmQoUKFDwzUIhPAoueZReFO1sfanuwFcnPG2tFuprRUWlJzU85RXdKzyVNc0AJPtpOFrTIBKa4EAd4aHympeuFJ7qFnffnC4Uns7WtUYP4emk8LRYvYSnI1pttvb/DvGj8ATKFB6RzPgKH9B2ofAEtSs8viOiPQX4TV2ksHnUjyrzUewuOXHyh2+C9BitZzhVcxcnq2+m1XYGrTqCEQlv0i/i9h495RcEgYO1f6XZVkiQJoZZiU/5rEtyuuysLX8OARdDw6eTFTpaOi44+bT8QwDmJywkJkCaFvhuiUiU5iZMpF+w9zNTZzGwrlxcGN+ZJW009/pFMaL6itSRJAR5780P807S5rAxICKWmcleu9ihqnJyG+sJ0molvXfabDZWnxGtYTePkZ73h0dF4jRvcDZxHYi73elsbzZ61SQpgXA4XXx+SLRqLZ8iJUkAO47kYbU5SE+KYmiWXDFpbG7j0LFCABbPle/vgSedbeaswX5JkQf7tp/H6XSROSCB9F70BDO3WTm2xx2N3YfNRjva2WZeoRAeBQoUfLdQangUXPIouyguXFP7mvDkfTXC46nfiY4JJdRHP5yOsFrt1Na4E9JSu7C0VYsKT5Ifhaeyzq0AxUX4XAR3rfC4CU+klPA4nC5vrY5M4RGta7F+LG0du96D184WpNVJaisAzA6R8AR1IjxehacrS5tLNhas9W9pA3qk8EToMwjTpWC0V1DZdoj0MHlHaH/wkB6AKuMqcusfxyU4SAy9ulc2pDZbPsXN/6TetFk8LloSQ68hPfJBArQ9tyXlGz6nwLgRFWpmJv6eIK3vWPPddR9Say0hWBPBkuT7ZON763dTbakiRBvK4sTLJGNnmvM53pSLRqXmxjRpQ7n/FO3BLjgZFZXO2GgveSkw1LG96iIq4K6BU9q3O1wu3j5/DIC7h06QXLOVp0R158qBw4joQKrXncul1WYjIyqSqeleBclks7c3G71+nHSxv/tcEY2tJmLCgpk5RFqDc+h8CfUtbUSGBDJzhLxZ6Ma9IlFZOn2oz9/pl7vO43QJDB2YRLqfGHmbzcG+vWKN0tx53dvZdm4R1ajZvVR3ju7KxWZ1kJQW06fpbIqdTYECBd8nKIRHwSUPr8LTd950+OoKT2/sbJXuUITQ0EDCw/2TI4/C44/wVNWJpCnJR/0OeAlPVzU8iZ0sbQ1tJgREwtFZyfFY2jrX8DR7FJ5AqcJj8FO/A2B1+ba0eciM2odQrVWLhMfhs4ZHJGcmhx+FRyf+PhttVT7HQbS+pYbM4FzzB5S07uwV4RH3l5Keiw1PUNz8HBEB44kIFH9CdANRudUrl2DDYi/D5CjCZC/CaM2h3vQlIAAq4kMuJyPyRz1KYeuIest5DtX9DYAxMfeSGDzW57xy0wX21olhBkuT7ydEK73P2hxtrK9YA8BlSVe0k0oQFaR3ikV1Z1HiFBKDvAv8BquRNWWiLfDOrDkScuCp3ZmfPJisMK8SurEkl0qTgZjAYK7I8qojZYYWthSLlq7bR3ijtAVB4N0TOQDcNHqUJOVtw+lcWq020qIimJwpvXafHBJtXleMHyrrvbPWbWdbMnEwOq10rKrewLHzZYDvZqOCILBxm3jsrtSdgwfyMZlsxMeHM2yYvKFpRzTUGTl1VIzHnt1LlWZvBztbX6azKXY2BQoUfJ+gEB4FlzzK3DU8/Qb0HeGx2xzUVrhra7K6Jy4dUVEmNghNSff9ZLcjqtyEJzk5ssvFSG29m7DE+yY8tY3uHjc+CA1AnZvUxEfKbWsNRjd5CetEXtwqTlRwkKzhYou7ViciUFo/0ua2rsmDCXyTGvAqOZ3fv6dOx6eKoxEJlckhj5eO0EUC0GhrkI0BxAWKBeRV5nyf4x5khS3kXPMHFLduZ4z9XsJ0vYs895AejSqYCsM72Jy11Jk2UmcSC/u16ghCdIOwOWswO8oBOXmLCZ5PZuSjhOgH9uq1ARqteXxZ8WOcgo1+IdMYHnWLz3lWp4nVZX9FwMWwiBkMjZCHGXxctgqDo4WEgERmxUlDBw40nOKsoQC9WidLZnurYAdWl53hEalMjvU25ixpbWRtmWg1u2egNKL65dMHALh10FjJ/fLmKTHEYHq/dAZGewnSvpJSLtTXE6zTcfVwL8EQBIH/HMoB4PrxIyX3cEldE3tzi1Gp4OpJUgJR19LKzhwx+vmKqXI1Zf0uUWkZPzSVRB8PGM7nVVNYUo9ep2HeDP/pbJvdRGTuvKGyz1dnbNt4EpdLYMjI1F43Gz3kts1NX9x3sdFNtQaOu3sHzVoxoZvZChQoUPDNQyE8Ci5p2Cx2qopqAUgf2HeR1DXljbhcAoHBeqLietdMr8qdupbcRQhB++u4wwgSEn0TGQ/q3DU6cTG+m0rWu4MH4qLk43aHE4NJVFiiw+ShDk1uYhMd2qkexyLuEx4krwlqs4k2tBB9Z2IjLtoDtD0PIPA8kffM8SDIHVPtia3uiAid+D6b7UbZWEKgSHxrrL4ta/2CBqJCTYu9jhZbHRF634Q2JnAwKcGTqTAd5HTjO0xN+KXPeV1BpVKTHf04GZGPYLSdosVylBbLEVqsJ3C4WmixekMR1KpggnWZBOkyCNZmEhuykFB975pLetBozWNL+Q+xugzEBgxlRsLv2tWkjhAEgQ2Vr9BsryFCF8+y5Adkc862nGZ/wx5UqLgt4y60au/v1uay82bhZwBcmTKH2ADvPV9hamRN2REAHhi4UEJoX8ndg1MQmJnQn1HRXnVjW3k+uc11hOr03D54vPf9mE184I6ivn/MRMn5vXlEVBquGTGMiA7K4sGiMi7WikTo2rFS4vLBfjHgYMbgTNJiIyVja/aeweFyMTo7mYH9pPeGw+linZvwrJjjm0Bs+FIkcrOnDSLMRz0dQH29kcPufjqLuyEigiCwZZ2YcLfw8tFdzu2Mg1+exWqxk5IRy8ARXatIvcGuNUdwOV0MGptBv68Q6qJAgQIFfQ2F8Ci4pFGeX43LJRAaEUx0N6ShN6gsEdWB5PSYXttAqtypa0ldhBB40E54/FjVQKzzMRhFJSPOTydzT0JbTGSIbKzRreBo1WrCg6ULMKvdgckqkpfITp3iDWbxNcMC5SlgJru7d46M8IhKToA/e5rPehzfSk6Qu6moxQfhidSL16HF3iobiw8QF2C1lmoEQZD9/vSaIJKCsqk051FqOssI/WzZMTwYGX0HFaaD5Bs2MjL6dkJ1X61WQaMOJDJwIpGB4mJdEBwYbecw2QsI0CQRrMtAr0noE8tRZ7KzIOU59Br5fQFwqnkHZ1p2oULNVamPEaiREmaL08x/SsSeCXPi59M/TKo0fVL2JdWWBmL0EVyTOl8y9q+8L3EITibF9GdCTHb79uLWBtaWiqTgh0NmtW8XBIEXT4k2tx8MGiup0Vl5+gQWh4PhsQlMS/Fa03Jr69hTXIJapeL2cVK73soD7nqfMcMkpL3NYuOzI6Jl7abpoyX72J1OPt0jntu1M6U9fgAOnCyirqmVyLAgZo3Llo1brHa2u5uNLp3n33q2desZXC6BYcNSSE3rWgk+f7qcsuJ6AgJ0vU5n2+EmSnOWj+lTO9u2jw4CMO+6yX12TAUKFCj4OlBS2hRc0ijJrQQgbXBSn/5Br3AHDySn987OBr0jPNXVHsLju/YGoM5tVwsM0PntwVPX5FF45AvbBoNIeKLC5Na0ZpNIajRqlYzYGNwKT2fbGnita8Gd+o94CY+07sH5FRSeQDfhMXel8NjkCk98oEh4TE4TrQ45IQJICxaLxEvbzvkcbz9W0AiSgicg4OR04ztdzu0NVCot4QEjSQy9kqigyQRoE79BsuNbFWywVrKp6l8AzIq/kdRguf1qdfnHNNoaiNHHsiJFGkNdbW7g47IvAbg760qCtV5Sca6lnC+qcgB4cOAiyX4vnN+FC4FZCf0ZGe21Ce6uLOJkQxWBGq0kirrNbuOdM+LC/f4x0hCDt46K4QaLBg4gLTKyfXtRfRO78opQAT+YNFry+uuOnaPVYiMjLoopA6T9cXafLKSupY3osGDmjekvux6f7RBVpmUzhqLXyZ8n7j6QR5vJRmJ8BKOHp8rGQSR2mzeJpGrxEjmp6gyPujNj/lBC/ChGvtDc0MrxfXkAzFnuu3brq6D0YhV5J0vQaNXMVOxsChQo+J5AITwKLmmUXBAJT/qgvrOzAVSVeAhP93U4HdFmtGBoEQlGUg+89rU9UHjqG9xkJibU76K4waPw+IiW9ig8MeFyMtTc5k5VCwmSHdtDeHwpPK1uS1toZ4XHIVraOjcddbm6SlzzrfAEewiPw4fCoxMVHl+WNr1aT5ReJJu1Vt/R02khYq1Hqemsz/GOGBV9JwD5hg20dhFl/V2jN2TH6bKzuuyv2Fxm0oOHMz3uGtmci8ZcdtZtA+DWjDsJ1EgX268XrsbmsjMqciAz4qQhAv/MFeuUliSPYUiEl9TkttSwoUy0hD06bI50n1NiRPXNA8cQG+S9V1edO0Wz1UJGRCRLsrwKU7XRyPrzoppy13hp4fx/DokkYdbATDJivJ9Dl0vg/b05gKjudH4A8NFu0eq2YtpwGaGpaTCy/6QYHLBitm8b2iZ3WMGSecP81uWcO1tBWVkjgYE6Zs/p2rJoMdvY5U5nW7h8TJdzO2PXhhzRdjYqleSM7uPxe3zc1aJNcdycYUTG9s7uq0CBAgXfFBTCo+CShkfhSR/ct4Snsp3w9G6hUOmu34mMDiHYjxrTER6FJ7ELO56nfifWj53N7nDSZBSJS1cKj6/6HQ/hiQqWJ8R5LG3hnQiPIAiYPAqPzp/C0xtLm58anq4UHr1/wgOQEOCu47H4ITxuhafOWobJYfA5p/1YQaNIDBqLCwenGld2Ofe7QoMlt8dkRxAEvqh+nSpLPkGaMK5M/QlqlVSRszqtvFP8FgAzYmcxJFyaNna44SwHG06jUam5P1sat72r9jwnmooJUGt5cMACyX7Pnd2BACxJGcrQSK89cG9VMcfrKgjQaLlvuLcBqdXp4PWTYo3O/aMnShqNvnM8B7vLxYR+KYxO9h6rxWzhsxxRubt9slTZOJBXQnFdE6GBepaPk0ZBF1Y1cORCGWqViqtnyO1o63adxiUIjB3Sj7Qk+cOMqpoWjp0qBWDxHP/Ws01udWfW7MEEB3f9HbF3+3lMbVaSUqIYMTa9y7mdsWOtSPpmX947otQd9n4uWgVnrhjfzUwFChQo+PagEB4FlzQ8CW1pg/q2D0R1mUhckrrx13dGTVUzAInJ3as7NpuDlhY3UYn3b2lraHKrNz7IDECTm9CoVSoiQuXEpbnVreL4sMMYzO5gAh8Lr/bEtQCpimNzOvFQk6BOhMfhEolN5147ngWxlNKI0LuL4C3uBqQehOrE8zXYzbJ9YvQiQayzNPk4IiQHiapCqanE53iwNpz4AHEBecF4yOecjhgdczcAeYZ1VLYd7mb2twdBELjQ8hmbyu/vEdkB2Fv3MccavwBULE95hHCdnNR/Ur6KWmsNkbooru53g2TM5LDwcv5HAKxImUNaiPezZ3Ha+UeuGFF9Y8Z0EoIi28cO1hWxo/oiGpWKHw2dLXkPfzmxC4CbBo4mPsh77h+eP01NWyuJIaFcOchLUJrNZt7LEdWYuyZIF96rjpzCZLczMD6WSZlSW9l/douL9RUThhESKL2vP9iRA8DMkVmyflV2h5M120X1xl9YwedbRCIzbmSa3/j41lYLO7aLZKwndrbNa8XzXbh8DGp1z/+cl+TVcOFkKWqNmpnLun+dnqI4t5KS3Eq0Og2TFvVd6psCBQq+Ol5++WUyMzMJDAxk3Lhx7Nmzp8v5u3btYty4cQQGBpKVlcWrr74qGV+5ciUqlUr2Y7HIU1EBnn32WVQqFY8++mhfvaWvBIXwKLhk4XQ4qSquAyC1f99FUrtcLmrckdTxvYiABahzKzZxPQhQaHTX5uh0GsLC/Hvzm90WuagIuUIDYGhzKzGhgT5tNMZ2UiN/DZNVJDVBnaxpADa3PU3fyZ7mdHlpS2fFxn89jngMjwLUEeHtxMYq2R4fIC4666wGXJ3sbqnBYp1Og62FNoecEPUPFa1PF40XZGMeDIuYAcCZ5t1+53iQEDSaQRFXArC35mkszpZu9/mmYXMa2VX9Kw7W/hmnYCMleDILUv7ZJdnJadrGjtp3AVicdA+DwifK5pxqzmFX3Q4A7si8R9JzB+DfxZ9TZ20iITCGm9KlTUbfKdxFlbmJhMAI7sia3b7dKbj446mtANyQOV7Sd2dT6QVONVQTotXz0HBvA1KLw85Lx0Uy+tDYSRLV8N/HT9BmszEoNpa52d7GoBa7g3cOiiThnunjJcpTXlU9+y6IAQc3T5eqHs2tZj4/KBKRm+fK612+PHSBhpY2YiNDmDthgGzcZnfw+VaR8FyxZLRs3IOtW85gsdjJyIhlRDepaVXljZw6VoxKpWJBL9PZtnwskvJJc4cQHef/YUpvsWuN2842dxhhPgJSFChQ8O3iww8/5NFHH+XJJ5/kxIkTzJgxgyVLllBaWupzflFREUuXLmXGjBmcOHGCJ554gh/96Ed8+umnknnh4eFUVVVJfgID5WuII0eO8NprrzFy5Hf/AEQhPAouWdSUNuB0uNAH6ohJiuyz4zbXt+KwO1GrVcT2Mvmtrka0R8V1EULgQYO7Niemi9oc8BKeSD+Ep6XV3RPHT0Fzq5vwhAb5SFtz1+IEB+hkY556nABt5wACL/noXJPjj/B4FqsWhw/Co/et5MQEhKFChVNw0WiTNhEN0Qa1qzxlJrltbYA7TazCXEabnwakwyNnAlDUdgqjvdHnnI4YH/tDInTpmJ317K7+DXaXnGh9W6g1n2Zd6W2UtO5AhYZxsQ8zL/mvftPYAPKMx1hf8QIAU2OvZmLMZbI5LfZm/l38JgALEhbLrGznWgrZUCk+PfzRgBsI1HjvqbK2Bt4pEsnjjwcva48VB/is5BTnW6oJ0wXwcIdkNofLxV9PiPvcPXSCpHbn/XOnqGlrJSU0jOuGeC1mRquVfx8T7VoPTpkkId1rcs7SaDKTHBHOkmGDJOf+jlvdmTeiP/1ipJ/rNftOY7E7GJwaz9gB0n5LgiDw4Wbx9a6eN0rWiBTEsIKmFhOx0aFMnygPO/AcZ9068RwuXz6225CKLzeICtbYSVnEdVHj1xk2q4Mv14g2wMXXTepmds8hCAI7V4tEavZVcqKsQMGlBpPN/q3/9BZ///vfueuuu7j77rsZMmQIzz33HKmpqbzyyis+57/66qukpaXx3HPPMWTIEO6++27uvPNO/vrXv0rmqVQqEhMTJT+d0drays0338zrr79OVFTvHg5/E1BiqRVcsigvEPusJGfF98ru0R086k5MQgRanXxx0xXqanqu8DTUi4Qn2k9vHQ+aDW5LWoTcrgZgaCc8vsc9Ck+YD9uaJ5K6c9oagNVNTjorPB3JTOfr3p3C09m2BhChE8/bYJPK5Vq1hpiAUOqtRuosBmIDpDVM/YITaLC1UGaqYXB4ZqdjRpIQkEiNtZqC1jxGRo6WvW6UPpF+wYMpN+WS0/QlM+Kvk82Rnk8gMxJ/x6by+6kyHWFL+Q+Zl/wXArXf3he9S3BypuldchreQMBJqC6ZWYlPERs4tMv9Kkx5fFL6RwRcjIycw7yEW2VzHC4HrxW8hNFhICWoHytSrpaM21x2/nlxFQICCxImMzrKSygEQeDvuZ9jczmYFDOAOQleotTmsPGPc9sBeHDwTKIDvMT9o/xTFBoaiQkM5p5h3kW02W7nZbe68/C4KRJ1590TJzFYrWRHR7N4oFdtcThdvLlPXOjfOXUcWo333qwztPL5cbFR5m2zpAEHdqeTj3aJ5OLGOaNlROR0XhXni2rQ6zRcOdf3U8zPNomE6PJFI9H6IEQAp0+VUVrSQGCgjgXdxEu7XC62fp4DwIJe1uAc/PIshiYTMQkRjJvR+4a1/pCXU0JVUR0BQTomK3Y2Bf8DmPG319AE9DwZ8evCaRX/BhoM0rrSgIAAAgLkf79tNhvHjh3jF7/4hWT7woUL2b9/v8/XOHDgAAsXShtEL1q0iDfffBO73Y7ObVNvbW0lPT0dp9PJ6NGj+b//+z/GjJF+Fz300EMsW7aM+fPn8/TTT/fuzX4DUBQeBZcsKtyEp1923za+q638anY26Kjw9NzSFhPdNeFpanYrPOH+FB6REHWr8ATKbWtehceHpc3pW+HpSGbkCo9aNge8qW0WH5a2MLelrcVHrU5cB1tbZ6QFi0+cSn0oPOBVebqytU2IXgrA4cbPcbi6f7oWEziIhSnPE6AOp956jk3l92O0V3S7X1+gwZLL1opHONHwLwScZIYt5PLUf3dLdhqtlawqeQq7YCUrdAyXp/zQp7qwuuIj8lovEqgO5L7sh9GppffEh6VbKDfXEKUP566sFZKxPXW57Ku7gFal4adDL5cc/42L+6iztJIWEsUtWd4YY7PDznMn9wLw8IiphOq8f9D/czaHerOJ1LAIrhnkJU8mm709ivqBydIQgy/OXaS82UBUcBBXj5EqU6v2ncThdDE6I4lR6dJ6vx05+dQ0tRIdFsyi8VJVCODDLaIqs2jKYKJ8fAYLims5da4CjVrF5Qv818tsdCs2c+cNJaSbQJPTx0uoqWwmOCSAqbN713z2i49EorjwmvFo/JCvr4Kd7nS2yYtGEdSLeGwFChT0DqmpqURERLT/PPvssz7n1dfX43Q6SUiQroESEhKorvb9d7G6utrnfIfDQX29GNY0ePBgVq5cybp161i1ahWBgYFMmzaNvLy89n0++OADjh8/7vfcvgsoCo+CSxYVhbWAqPD0JWo99TvJkb3et13h6ZGlTbRaRcd07YVv6sbS1l7DE+J7EWI0+Vd4zF1Y2tpreDr11HF1WcMj/ts5Ytqr8DhkzUAjPJY2m7wgMj4wgvOGCmot8pqZbglP6CD21u8mr9U/4RkaMZ1t1e9gcNRzunkHY6IX+p3bfk5BI1iS+i+2VvwYg72MjWX3MifpWeKDvpmn3g2WC5xsfJuyNtH6pVUFMin+MbLDlnZri2p1NPFe8e8wOVtICuzPtamPo1HJ/ywcbjzIlzWbAbFuJzFQSgouGkv4uEyswXmg/7WE6bz3osVp42/nPwfglszppId463OqTC28lXcAgJ8Nn4++g1Lz9vmj1Jpb6RcawU0DR7dvb7PbePWEaJ360fgp6Drcf++fPEmT2UxaZASXDfESAUEQeGOvqO7cOmkMQR0US5PVzof7RbLRWd0BWLXdbVebMUIWRV3baGTH0XwArlvou5fNZ5tyAJgxeQCxftTa1lYLu3a5G5Iu7T5EYOt68ZizFw0nIFD+2fSHmvJGTuzLQ6VSsejavrOduVwudn8mEh7FzqbgfwV7HruX8PC+q4HrDgaDgaQ/PkFZWZnkdX2pOx3R+e+Ar4bb3c3vuH3y5MlMnuxtKjxt2jTGjh3LCy+8wPPPP09ZWRmPPPIIW7Zs8VnX811BITwKLllUFooKT0ofE566KnFxHd+DpLWOcDpdNLptaj0hPE3u9LXobhSe9tCCSN+Ex9jmDiXw89S1zSIGE4T46KfjITwBWvlXhd2t8Og6ER7BZ9aaCE86myetzYMgrbhocwkCVqeDQK13ERepFy1tjTaT7HgJgaJSVmmSp7F50sEKW8t9fsEPDBMXxCVtRRjsBsJ18t+JRqVlYuzlfFn9NjtrVzE0YjoBGt/XuSMi9OksTX2NLyseo8mWxxflDzIs6iZGR9+NRi1Xy74K6ixnOdW4kvK2fe4tKrLCFjE65i7CdCld7gvQZKvmveLf0WSvJkqXyI0Zv/b53kraitrrdhYnLmNMlDT1rNVh4o/nV+IUXMyIG8O0WOmC/bX8bR2CCuZIxv50eisWp4PxMWksSPYSlHpzG6+cOQjAT0bNkFjWXs85SqPFTGZEFFcO9KpXbTYbrx0WF933T5ooSQLccaGQ3Jo6gnU6bpwgPb9PD53GYLbSLyaCOcOyJWMnCys5WViFVqPmmplywvrptpM4nS5GD0phoI8mxAajmc07xLCDFUv8W8+2bD6NzeYgMzOOwUO6jtBvNZrZ/aXYH2r+ZaO7nNsZWz8VSd/oqf1J6EHj457i5N4L1Fc1ExIexLh5w7rfQYGCSwDBep1Pu/c3BYf7tcLDw3tEtGJjY9FoNDI1p7a2VqbieJCYmOhzvlarJSbGdyqtWq1mwoQJ7QrPsWPHqK2tZdw47wMkp9PJ7t27efHFF7FarWg0facu9xSKpU3BJYvqkgYAEn0sRL4OGmtFwhPTA9LSEcYWEy6nC5VKRaSfCOmOaHETmQg/yg2A3e7E4q6z8UdoTG5CE+zDsgZgs7uVGh/1SE43MdFpev5V0ZEAdSY2ITrxHNrsUntYmC4Ardvu1miVWteSgyMBUQ3ojKxQkcwWtNbIxgaEpqJVaWi0Gai01MnGYwJiSQ/OxIWLY03+o6QnRC8lSpeI0dHAjpp3/c7rjGBtLIv7vUx22BIEXJxpepc1JddzpO55asw5uARnj48F4lO2FlsJuc2fsqX8R2wsu4fytn2oUJMZuoAr0t5lRuJvekR2Ks35vFXwMxptlUTo4rk543eE+qg1arY18VL+c9hdNoaHj2RFirQBqSAIPH9xFTWWBhIConmo//WS8ZNNJbxfJNrSfj50uSSoYH9tIZsqzqFGxa9HLZYQ0r/l7MZotzIiJpEVWd4FdK2pjddyRFLz00nTJaRm5bHjNJrMpEdGcuUwLxFyuQSe3yGqSLdMGk1khzRCi93BWzvE4909d4LEAgfw9hfi2LJJQ4jr1LTXbLGzepu7tmexb3Vn3eZTWKx2sjPiGDMi1eccl0tgrTteevkVPQgr+PwkVoudjOx4ho70fUzfr+Ni62qR8Cy4ekI3s3uHze+KpHvO1RPR+1CDFShQ8O1Dr9czbtw4tm7dKtm+detWpk6d6nOfKVOmyOZv2bKF8ePHt9fvdIYgCOTk5JCUJD5knDdvHqdPnyYnJ6f9Z/z48dx8883k5OR8J2QHFIVHwSUKl8tFbblIeBJ62SunOzS463Cie0l4mtwWtfDI4B555w3uMIJwP2EEAG0mb1RziJ8mhWaLSC6C/CxEPNa0AJ3868ATMe0rztp/4pr3vVmdTgkBCnXHW7fapBHTKpWKmMBgasytNFpMJId4r21KsKjilLc1y86hf5hoWyswym1rARo9g8IyOGso4HRzPilBcqVvUswUSkxFHG44wJz4+bJxAJ06gKUpD/Be8W853LiBEZFzSAmWRw/7gl4TwvTEX5MWOpMDtX+mzVHDueYPONf8AYGaSFJDZpAWOpOEoLGoVVoQXG59TEDAhc1ppNp8nCrTUarMRzE5vMRNhYassEWMiL6VCH1aj84HIN94jI/L/oTdZSExMJMb039LmE7+tN/qtPJS/j9ptjeTFJjM3VkPtNdgefB55R721Z9Eq9Lw+JA7JFY2k8PK709/jAuBZcljmRE/pH3M4rTz2xNiP56bsycwONKb8HO2sYYP8kQi8Zvx8yS2yH8e2Y/JYWdUfCJLs7wF901mM68fFhfzj06fKrnntubmk1tTR4hezx1TpZa11YfOUG80kRQZJms0ml9Rz+7ThahUcNsCeRPNDXvPYmiz0i8+ghljs2XjdruT1RtEInP9FeP9Epnjx4spL2skOFjP/AVdqyOCILD+Y5GEXXbthG7JUUecOlRIbUUTwaGBTO0mFKE3MDa3sc/9PhfeNK3PjqtAgYKvj5/85Cf84Ac/YPz48UyZMoXXXnuN0tJS7r//fgB++ctfUlFRwTvvvAPA/fffz4svvshPfvIT7rnnHg4cOMCbb77JqlWr2o/5+9//nsmTJzNgwAAMBgPPP/88OTk5vPTSSwCEhYUxfLj0OyYkJISYmBjZ9m8TCuFRcEmiobpFjI7WqInrpfWsOzTWioQnJr53kdSN7pjpqOie9adoJzzh/gmP0Z3AFhKsR+NHhfEkrQX58frb2tPW5CTM5VZoNCr5sf0Rno6pbTaHEzoIS57C81Z309KO8BCeeovUupbiVnjqrK1YnHYCNd73kRUmyvK1VgMtNhMReqkaNiKyv0h4WvJZnCR/ojU+ahIfl62ioC2femsdsQG+1cDs0DGMiJjF6ZZdbKh8kbuz/45a1fOnVGmhs0gKnkil6RClrbsob9uPxdlMnmE9eYb1PT6OWqUnPnAEScHjyQxbQJiua/tTZ+Q0bWN9xQsIuMgMGcV1ab/0aWMTBIF/F79JiamIEG0oDw/4sazfTp6xlDcK1wBwZ9YVDApPl4y/cOELyk2NJARG8NgQacT1S+d3U9rWREJgGI8O9drcBEHgt4e2IgCXZQxhQoJXwchvauCD82IvmyemzJIs9l87dIRWm40hcXEsG+wNFnC5BF50qzu3TRlDVLD3s2RzOHjTre7cNXeCLE565RZxbN6YAWQkSgmh0+Vi1RfiIv+GxWNlyhDA9r251De2EhMVwrwZQ2TjHqz9TAxZWLRoBMF+Hlp4cPJIEeUl9QQF65nXg1qfjtj6ifh+Zl02qld1P91hx6eHsVsdZA7rx4DR6d3voECBgm8N119/PQ0NDTz11FNUVVUxfPhwNm7cSHq6+FmtqqqS9OTJzMxk48aN/PjHP+all14iOTmZ559/nquv9qZyNjc3c++991JdXU1ERARjxoxh9+7dTJz4/a7fUwiPgksSNaVimkhcSlSfJhG5XC4a64wAxMT3TuFpdqeuRXYTM+2BoaUHhMddnxPqJ5AAaLe8+VN4rB5Lm4/r5BT8KzyeBWfnih21SoVWrcbhcmHrlLoW5lF47L4Ij0gEGyzSvjiR+iCCtXpMDhuVphZJU8pQbSBJQVFUmZsoaK1mbHSWZN+REQP4gM2cbs7zWccTqY9kUNgQco3nONJ4kCVJl8vOy4OFSXeR13qMaksRhxrWMSX2Sr9zfUGnDiI9dDbpobNxCQ6qzScobd1FaetuzM56P3upiAkYRFLwBJKCxxMfOBKtuutFsS8IgsCeuo/YWfseACMiZrM85Ydo1PJ7QhAE1lR8zNGmQ6hVGu7P/iFxAVJ1rM1h5o/n38YhOJkSM5LlybMk4wfqLvJpmZgG9psR1xCq896fuc3VvJknRqL+ZvRSSframsKzHK0rJ0ir44lx0nqfPxzYhVMQmJ+RzaRkLxGqNhp554QYLPCTGdMkitAX5y6SV9dAWEAAt0+W2s4+O3yW2pZW4iNCuXKiVFmpqG9h81ExzOL2hXL7197jhZTXNBMeEsBlM+RPLAVB4KN1ouJ01bKx6PzE19dUt3DwgBh6sHyFPDChM9a7Scu8paMI7ibJrSPajGb2bT4NfBN2NtGyuOimab1SnBQoUPDt4MEHH+TBBx/0ObZy5UrZtlmzZnH8+HG/x/vHP/7BP/7xj16dw86dO3s1/5uAQngUXJKodhOexLTYbmb2DoYmEw43QYiKC+tmthRNvVB4BEFoV3giurC0tboT2EK7WPyYLF0rPHaPwuPD0uZJXPP1BNuzthEEeUhBgEaDw+Vqb07qQai+a4UHoKGTwqNSqegXHMlFQy0VpmYJ4QEYEJZIlbmJfGONjPAMCs9Aq9LQYGuhylJPcpBcwZkYM4Vc4zkOdUN4QrSRLEi4nfWVL7Kz5n2GhE8lUv/VIs/VKi3JwRNIDp7ApLjHsLmMqFABavd1VaFCjUqlQaP6ek/jbS4LX1S+Rk7zlwBMi72auQm3+l2cbqxazxfVot3slvTbGRQmjT0WBIF/XlxFtbtu55GBN0mOZbCbefrMagCuT5/ChBiv3cspuPjVic9xCgKLkocwP9mrxhhtVv5wbAcAPxwxVWJr3FNWzPaSQrRqNU9MkZKr5/cfwOpwMj4lhdlZ3n5LTpeLF3eKwQe3TxlLeJCXdNkdTt7YLpKHO+eMl/WSemfrMZwugclD0hiaLv8dv/+FqMqsmDPS5+fq9PkK8gpr0eu1LF/kX4lZv/4ELpfA2HEZpHVjva2vNbB/p5jkdtk1vSMtuzecwmqxk5odz+DRPbc/dof8U6UUnC5Dp9cy99q+a2KqQIECBX0NJbRAwSWJmtJvpn7HY2eLiA7pddPRZnfqWlQPFJ62Nms72ehK4WltV3j8E57uFB5PDY9OK/868FjaOsdLg9fm5uwUTABeW5unOakHnhoeQ6caHoDYIJHw1JnbZGMeW1tpqzyNzVPHc8FQKRsL1OgZFCZK98ebcmXjAGMjx6FVaak0l5NrOO9zjgejoxaQFjwMu2BlddnfetSbpzuoVCoCNOHoNWHoNSHo1CHo1MFo1YFfm+yUmc7zWv4jbrKjYknSfcxLvM0v2fmiagNrKz8F4Jp+NzA9dqZszmcVO9lXn+OzbkcQBJ49u4Y6q4G04FgeGrhIsu/beQc53VRJmC6AX41aLBn7W85u6i1tZIZFcddQ74Le7nTyf/tEIvSDYaPJivTayy7W1/PJaTGx7OezZkje19qT5ymsbyQiKJDbJksT0j47epaqZiOxYcFcPWmEZKyupZV1B84AcMciuUXjdF4lORcq0GrUXLfQd/KaR91ZOGsoEX4+v2azjQ3u5qFX9EDd2fDpUVxOF8NGp5E5oHdEe/PHotq24Gr/tURfBV+41Z3JS0YR3k2apAIFChR8l1AIj4JLEvXu5qBxKX0XvQrQ7FFpYnun7gAYm0XFJqwLxcYDk0lUQHQ6DXq9fyHW4lZvArvw5NsdvuOjPfAIND5JjcY/qfGEHHQmNQDh7r4ABquU2MQFiepWnUlOavqFiDVRpa3NsrGB4aIyc6FFnsY2MlJ8Yn2ssVA2BjApRlzQ7q71LdEHa0OYHiuqBh+Xr8IlyN+rByqViuUpPyRAHUK5OZePy/6I1SmPy/6u4XDZ+LJ6JW8X/oJGWxXh2lhuyfg9E2KW+d3ni6oNrK74CIDlyVexMHGJbM7RxnO8VbgWgLuzrpTV7awtP8q26jNoVGqeGnUdgRpvAVeeoZbnzonE5fERC4kP8n6GjtVV8O9cUTV5atJCSQz1v8+c4GJTA1GBQTwyfkr7dkEQeGb7LlyCwMIB/Rmb4q1nstgdPL9DtM3dO30CoR0i1612B//aKhKAu+ZOILCTsrly8xGsdiejspIYP7Cf7Bq8+ZmoGi2ZNoS4KPkiv6yyiT0HxXjWa5f7JzKbvziFwWAmKTmSKVP6+50HYLXY2eC2s11xfe+UlIuny7hwsgytTsP8q+ThC18VJqOF7R+5r8WtM/rsuAoUKFDwTUAhPAouSTRUNQMQm9S3gQUtjeJCPaKHwQMdYTS6CU8Xio0HJrdyExTUdc8Wq00kGwFdkCIPWfEXatAVPCTJ4ZSTgBB3TwCTTa5yRLrtQ80WabPQhBBxgWi0WTF1quPJCBfJabFBruIMiRTjLs+1yNPYRkVloFGpqTQ3UWFqlI3PjBNrN84aCqizyI8NcHnyCoI0wZSZSjjYsM/nHA+iA5K5JvXnaFV68oxHeLvwcZpttV3u822i0pzP6wU/YX/9akBgVOQ87h/wPFmho/3uIyU7V3JZ8hWyOfnGMp499xYuXMxPmMRlydJFbmFrTXuD0YcGLmJohJcs2F1OHj+6FrvLyayE/lyT7j0Xm9PJLw9sQgCuzh7OjGSvLa2mrZV/HBF/H7+YPJPIQO9nZ2dhEftKStBpNDw+S6pEvXvoBNWGVpLCw7hlovR9f3zwFDUtrSREhHLtZGlvnbrmVj7dI9a63H/ZFJkacq6wmgOnitGoVdy+3Dfx+PCzIwgCTJ2QTaYfS63T6eITd9ratddO7PazuW3jSVqaTSQkRTJ9rv8ABF/4/F2R+M1YMvIrPajxhx2fHMLUaiElO4HRMwZ3v4MCBQoUfIdQCI+CSxL1VeLCNjY5sk+P2+IOHoj4CvYNY4tH4em+caXJ7O6dE9wzwhPYRe8Lp5usaL8C4fHs42ky2hFBOv+EJ8LdXbmlE+EJ1esJce9X0yZVeTLCRHJaYmySJb8NiRQtPBdbauW9fbQBDHMvrn2pPHGBUQwLF+tIdtf5VnnCdOEsc9fvrKn4BKtTbrnriOywMdya+Qyh2ihqrSW8WfAYZSbflrlvCzanmR017/FWwc+os5YSoo3k+rQnuaLfIwRq/N+vcrKzQjanxtLA787+C4vLxqjIgTw84HoJGbA4bfwq50OsLjuTYwdwU4Y0nvi1C/s421xFhC6Q/xt7uWTff509yMXmemICg/nVuHmS/Z7Zv5M2u53R8UlcO9gbDmB3OvnDjl0A3DFuDOlRke1jzSYLr+0VycSP5k6RxK2brHZe3yaO3bdgkiyKfeWWI9gcTkZnJzNxsLzW5a21ojK0aOoQ+iVEysYbm9v4Yrtoh7vxSv+JRbt35VJV1UxERBCLFssbmnaEIAisWSUqKStunNSrEBZDUxs71+cAcPktvvtufFVsfl8koktvm4naR42fAgUKFHyfoHxLKbgk4bG0xfZxJPXXUnjcIQRhYf4T1TzwWNqCekh4ulJ4POqMv6fIXVn6PQqPL8IT3JXC4yY8zWaLbCwhWFx815haJdtTQsPRqFRYnA5qzdKxtJBoQrR6rC4HhUZ5otl4d2H80QbftrZZ8aLKs6vumM9xgDnxC4jVx9Fib2Zz9Ua/8zzoFzyIu7L+SmJgJm3OFt4peoLTzTu73a+vYXdZ2V+3mucv3sOeug9x4WRo+DQe6P8ig8L9258EQeDzyrXdkh2j3cRvz7xKk81ARkgyTw69C51aKznO02dWk99aTbQ+lN+OuEbSr+dccxUv5+4GxFS2hA5WtvyWBl445U5sGz+PqA4Kzv7yUtbl56JWqXh65nyJ5fK9nJMUNTURExzMA5Ol7/Ffew5jsFgZGB/L8pFSNWTVvhwaW030i4lgxQRpMltHdee+ZZNl6s7Fklr2HC9ApYLbl/smM59+fhyb3cmwQUmMHOq7AawgCHz4gUicVlw5rks7KohR1KWFdQQF61m03HeDU3/Y/PFh7DYH/YelMHhM30VGl1yo5OKJYjRaNfOUsAIFChT8F0AhPAouOVjNNgxuYtL3hMej8PSe8LQaxMV/T2p4zG7CE9ydpc0dSNBVnU+7pe0rPIXVtSs8cktbkJvwmO09V3gA4t22tpo2KanRqTX0CxXreIoMUmuaWqVicISo8viytY13p7MdbSzwmRo3PXY0atQUtJZTYfJtP9OpdVzd73oANtdspMkmt8d1RoQ+jtsz/8igsMk4BQdryv/O9pp3EbqoA+or2F1WDtWv4/mL9/BlzUpMTgPR+iSuSf0516Q9TrDWf2y63WVnZfEbrKsU09SWJ1/lk+zYXHaePvc6ZaYaYvQR/H74fYRopffvqpJ9bKk6hUal5g+jbyQmwEtoLE47Pz/6GQ7BxaKUISzr5yUZLkHgiQObsLmczErOYnmmt/GnzenkN3vFVLlbho1ieJy3SL/JbOb5fWJvnR9Pn0pYgLc+p6LZwLuHcwD46YLpknveaLbylrvvzoMLJ8tq2nqq7iyYPIj0JHltoMlsY81GMR77xisn+g0HyDlRQl5eNQEB2h6FFaz7+DAA85eNIqQHD0s8cDpdbHhfvE6X/6BvI6O//EA87oT5I4iM6108vwIFChR8F1AIj4JLDg3VzQAEBOkI7YF9rDfwKjxfwdLmVnhCw3oSWiBaqrq1tFl7ovC4o6U1XS94fPAEtB6Fx+Ff4WmzyiOmI9oVHrNszFPHU91qlI1lhIkLySIfdTxD3XU8Z5uqZGMjItPQq7XUW40UtsoJTYQ+jDFRYgTy9tojsnEPxkaNp3/oQOwuGx+UvueTPHWGXhPEdWm/YGqs2Jhtb91HvFbwY442bMTilIczfF0Y7Q0cqF/DCxfvZXP1G7Q5monUJbA85REeHPAyQyOmd7m/wW7gHxf/zIGGvahRc1ParT5rdpyCi7/m/oczLQUEawJ5asQDxAZIHyAcrs/nhQtfAPDooKWMjc6UjD9zcjN5hjriAkL53eilkkX3exdPcLi2nGCtjmcmL5KMvXnqKPlNjcQEBvHYROn7+cfe/RisVgbHxXLtCGkPnH9u34fd6WRSRioz+mdIxv696xgGs5Ws+GiWjpHWnNQ2t7J6r391p6Csnh1HxCCCO/zU7qzfcpLWNiupyVFMm+g/hOBjN4FZtHgkEd18P9VWNXPAE0V9be+a+h3ZcZ6a8ibCIoOZddnoXu3bFZwOJ9vdqW/zb5jSzWwFChQo+H5AITwKLjk01rQAEJ0Q0eeN8IzNYiJXWFTviJTT6cLirssJCe2+YaDNbVXTd1GbA171pnOX+N6gK9takJtImbsIJmjxYVuLDxUVsM51OgBp4aKKU2JokY0NihSLvM81ytPYxkSLdTqH64tlYwEaXXu/l23Vp2XjAAsSxYXqxqq9mBzycwYxhe2GtFtQqzScaD7K7vqdPufJ91MzP/E2rkh5BJ0qgBpLERurXuUfubezrvyflJlye0SefEEQBGosxeyu/ZA3Ch7jHxfuYGv127Q6mojQxXFZ8kM8NPAVRkfNQ63q+j4oNZXwzPnfkt96kSBNMD8c8BNmx8+TzRMEgZfzPmqPn35y6F1khCRL5pS01fPLnPdxCi6WJI/hunTp4vezkpN8VHwcFfDnCSuIDvCqovktDTxzdDsAPxszq13ZAyhpaea5I6KC8Msps4gI8Koap6urWZVzEoAn586WKDgnyipZdyoXFfCzhdKI6upmI//eJdoZf7hkqkzt/NfnB7Da/as7b6wRz2fuhAFk9ZMHEVisdlatFonMjVf5DyEoKqrj0EHRFnd1D3rpfPbBIVwugdETMsnIju92fkesfku0ES66biIB3djmeoNDW07RUN1MRGwYkxZ2XX+kQIECBd8XKI1HFVxyaK4Te+V8E1aLNmPPVZqOsFq8hKG7uhwAm80dJd1Nrx9Prx6V2j+x07jHPHM7I0CnxeZwttcDdYQnztdokas4UcHuRqFtchUnOVy0NVUaDLKxbHcflYLmBtnYiBhRxTndILetTY4T1YPclhoaLG3EBEpthQuTRrKv7gJbqk5xT/95MrI7NXYUyUFxVJrr+KxiBzely2OXAdKC07kq5Ro+Kf+Qj0rfo3/oAFKC5PHEvjAqah4DwiZwqnkHx5u2UG8tI6d5GznN24gPSGdQ+GSi9AmE6+KI1MURrotFqxbvB0EQsDhbMTjqMdgbMNjrqbOWcdFwmGa7lACmBA1kTNRCRkXOQaPu2WL2aOMh3i5+A7vLRkJAIg8NeJTEwCTZPEEQeL1wNV9U70eFip8NvpXRUYMkcwx2M48dewejw8LwiFSeGLZCcr0vttTy2xyxeenDQ2YxNd7bENbmdPLonnVYnA6mJ2Vw22CvrcslCPx85xdYnQ6mpaRx9SCvBc7pcvHbrdsQgOVDBjMlzUtMXC6BZzbtBOCqMcMYniztU/PCpn1Y7A7GZqYwb7hUfSmqbmTtfrGXzyNXzpDdN3mldWw/kodKBXdf6VvRWPfFSRqbTSTGR7B4zjCfcwA+/EAMH5gxczD9+nUdmd/WamHTGpGkXd3LwIG8M+WcPlyIRqtm+Q+mdb9DL7Dx324iddM0dF0oywoUKFDwfYLybaXgkkNTnWiVivoGCI+nDiekB9HSHeGpyVFr1D1aJNjtvSM8vnroeKB2Ex6nX8KjwWj2NiDtiDA34Wm1yFPLYkLEa9DYJu9DkxwmXvsqg9y25mkcWdAkr5EZGSs2ET3fVIvN6UTfoc4iJjCEwREJ5LbUcLCuiGWpUjvTzPihBKi1lJrquWCoZHCEtGhco9Jwa8Yy/nh+JavLt7MsaToRet8xvfMTFnPecI6zhtO8VvASTwz5HQGa7pU5gGBtOJNjr2BSzHLKTOc50bSFsy17qbWWUFtXIpsfoo0kQB2E0d6IXfCdDqdV6ckMHcWgsEkMDJtAqK7ntWkOl4N1lav5olokIMPCR3BP1gMEa+V1aE7BxUt5H7K5WlQ0Hh5wPdPjxnQ6npNf5rxPqamehMAI/jL2FgI0XtLVarfyo0Mfi4QmPosHB0sjo/9xcg9nGmuI1Afyt2nLJPfuu2dzOFQp2tz+OHuhhHysOnmKU9U1hOr1/GK29Jhrcs5yprKG0AA9P54nXeCfLatm3TGxoezPLp8pIzQvrd2HSxCYNTKLUdlSFQu86s68iQPJTvWt7ry/WrR43XrdZLR+1NbaWgPbt50D4Pobui/0/+Kz45jarKRlxjF+atd9ejpj7co9AMxcOoq4pMhe7dsVqkvqObZdfA+Lf9C1dVKBAgUKvk9QCI+CSw7Ntd+gwuOpwwnvefEw0G5nCwrS98hm53CTD72u64+oxyal7lLhEe01Lh/NQ8HbQNTiU+ER1QdfhCc6RFR4Gk1mXC5Bcg5JboWn2WKhzWYjRO9VtTyEp95sosVqkViW0kIjidAH0mKzcLG5juExiZLXnBqfSW5LDftr5YQnRBvA9PjBbKs+w5aqUzLCAzAtdjTZof0oaC3no7Kt3JN9lc9rolapuSPzXp469yuqLJW8lP8cD/V/tMekB0R7XFrIUNJChrIo6W7OtOyh2lxAi72OFns9LbZa7IKVNkczbTS37xesCSdcF0OYLpZIXRyZoaPJCh2NXt27ew6gpK2YlcWvU2EuB2BhwhKu6nedJEXNA6fg5O+577Kz7hhqVDwy8CbmJ8oX5n/P/ZwjDQUEafT8beytkpACQRD41fH1FLU2kBgUzl8mXCkhNAerS3n1jKhy/HHKEhKCvfuWGZr54wFRPfjFlJmkhke2j9W0tvLX3XsBeGzGdOJDvTV0RouVv28TI5IfmjWZ2FAvkRMEgb+sF4952djBDE+T3k+ni6rYnpOPWqXi4SvkSsjFklp2Hs1HpYK7vqa688nHh3E6XYwek87gwXJi1RFOh5PP3FHUV908pVexzy2NbezaINr+lt/at6Rk03/2IAgCY2cPITmzdxY7BQoUKPguoRAeBZccmtyWtr5WeFwuF6ZWceH/VRWewKCe2Y/sdpF86PQ9VHi6IDzq7ixtbsXJavdBeIK6srSJ18AlCLSYLUSFeK9JWEAAYQEBGK1WqoxG+sfEeI+p15MYEkp1WysFTY2MTfQu/lQqFSNjEtlTVcyphmoZ4ZkSl8VbeQfZX1uIIAgy8rgwaZRIeKpP8fCgRbKFvVql5raMy/nNmVf4vHIPV6TMJj7Qt7UoXBfOA9k/4rmLfyHXeO4rkR4PAjWhjI+WWugEQcDsNNJir8PqMhOujSZMF4NO3fvjd4bD5WBj1To2Vn+OS3ASpg3jpvTbGBflu27E7rLzp/P/5kCDmLb2s8G3MiNOHoH8TuFuPik9hAoVvx95HQPDpZa49wqPsKniHFqVmucmXi2p22mxWfjJ3s8RgOv6j2RxutcmJwgCj+/cgslhZ1JyP24ZNlpy3Ge276TVZmNkYgI3jZbWjbyw4wANbSayYqO5uVOT0e1nCzhWWEGAVsMjS6WLf0EQeOEzkUQtmzyE7GS5evP6alHdmT9pEFkpMbJxq9XO+2vE2p1br/Wv7hiNZjZ8ngP0TN3Zs+0ctdUtREaHMG9p7+pkNn98GIfdyYDh/Rg0KrVX+3YFh93BFk/vndtn9dlxFShQoODbgBJaoOCSQ3sNT3zfEh5Tq7VdUQnpZQ2P2dyzvjoe9LSGx3M+XalGnjH/ljaR8Nh8EJ52S5tZrvDotRoi3OP1PsIJksLEp/CVPmxtnjqe/C7qeE7Vy9PYxsemoVOpqTS3UNImt8RNjR1IiDaAWksLOU1y+xjA2KjBjIjoj0Nw8k7x5z7ntJ9naH8eHfhTAtSB5BrP8XzeXzHa5e/nq0ClUhGsDScpKJuMkOFEByT3CdkpaSviD+d/x+dVa3EJTsZFTeB3w/7gl+xYnFaeOvs6BxpOoVNp+dXQu32SnTVlh3nxopjI9qNBi5mdMFQyntNYzh9PbQHg5yMWMCbGu9gWBIFfHdxMpclAelgkv50wX7Lve+dOsr+ilECtlj/PXixRhXYUFLLxwkU0KhVPL1wgCRy4UFPPe+4Y6ieXzEbfgXDYHA7+/rlo7bp11jgSI6X2xf3nSjh6sRy9VsP9l8nVm/NFNex29925a8Vkn9fu862naWxqIyEunMVz/as7az87jsViJysrngkTsvzOA/Faffqu2Jvo8msndhtc0hFOp4uNq0SSdtktU/s0tGX/xhyaag1ExYczeZESVqBAgYL/LiiER8Elh/ZeOTG9j47uCqZWsX5Hq9OgD+idOGpzhxb0dPHi7KZZaGd0FQDmWQT6ipYGCA7w2NZ8xEsHu+Ol28w+U8biwtxpbAY54UmNjASguEkeMT0w2p3GVi+PkB4TJyo+B2tK5eeq1TM+VmyguKXivGw8QKNjfuIIAD4qOSAbB5Fo3J65HBUqdtQe5XDDGZ/zPMgOHcCjA39KoDqQvNaL/OH87yg3lXW5z3eBVkcrH5et4g/nf0+5uYwQbSj3Zj3IfdkPE6bzTf6N9jaePPUSx5tyCVDr+e3w+5gYM1w2b2PFCf54di0At2bO5ObMGZLxSlMLDx/8CLu7386t2dII5Q/yTrK++DwalYp/TL+cEJ2X+Bc0NfL0/p0APD5pJukRke1jBouFX23ZCsDt48YyNMFro3K5BH6z/kucgsCCIf2Zli1trPnO7uOU1jcTGxbMXXOkZM/hdPGPT3cBcN2sUSRFS6+PIAi8+IG7OH/KYDJ9qDsWq53/fCLazm65epJfdae11cIn7ijqG26UR153xrEDBVw8V0lAgI7Lru0+ya0j9m85Q015E+FRfRtFDfDZv7YBsOQHM9B2Y7VVoECBgu8bFMKj4JKD0d0rJzyqbwmPuc2t0oT0/il8T0MIOqO7xZFGK36EnT4ipT0IcpMss1UeLQ0QHiKSGqNJHtUc6yY0ZrvDZ7+dlEgxTri8WR4xPcBtY8uvl6s4o+NFFedEjVzFmZyQhlalptjYRKmxWTbuaV65vsw3Ubk+XUy02lFzlgKjPO0NYHB4BitSZgPwfN4HGOxd98vJDh3AL4b8mtiAOBps9fwp92lymo53uc+3hVZHK2vKP+GXpx5ja80XCAhMiJ7EU8OeZXy0f/tUcVslPz7xN3KNxYRqg/nDyIfaexV1xJfVp3nq9CcICFybNpmHBi6SjBvtFu7bv4o6SysDw+P5w9jlkvv2fFMtvzsiNhH92ZhZjI3z1lbZnU5+vG0DFoeD6f3SuW2ENCDhDzt2UdPaRkZUJI9OlyaVfXD0FCfLqwjR63ly8WzJWHWzkde2ikECP7lsJiGBUmV1zd7TFFY1EhkSyN1L5NfowKlijp4rQ6fVcN81vlPOPtuUQ2NTG4nx4SydP8LnHIDVnx7FaLSQlhbD7DlD/M4DkWi9/4ZIxJZdM57IqJ43OBYEgU89+948tU+jqM8fLeTc4QJ0ei2X3Tm7z46rQIECBd8WFMKj4JKDsdlNeKJ7vljoCczfL88cAAEAAElEQVRtoq3r6xAebS8JT3fQtas3vgMJAAK7IzzB4vtpaZPb1oIDdIS4FaA6HypOvyiR8FQ0y+OnB8SKhCevwQfhSRAJz/n6OqxOqZUuTB/AWLfKs6eqSLbvwpQh6FRqLhpqudgiV4j6hyUyL3E4AgKv52+XjXvwg4xl9AtKoMlm4NX8T/zO8yA5qB9PDPkdg8OGYnVZeLngn/yn+C0abfL3923AaDeypvxjfnnqMTZVr8fqstAvKI2H+/+Ye7Ie9KvqAOypO85PTvydKks98QHR/GnUjxgcnimbt7v2PL8++SEuBJb3G89jQy6TkBm7y8mPDn3MRUMtcYGh/GvqjYTqvJ+PFpuFB3euwep0MCclm3uHScnF88cOcKquhoiAQP46R2pl21lYyCdnzqIC/rR4EUE67wK+xtDK37eJ9TePzptKYoTUrva3z3djtjsYk5HMZWOlTUaNJguvfC6qf/deNqWd8HvgdLna1Z1rF4wmOS6CzjCZbLz3qUiobr9+qt8HGUajuV3dufW26d0qtiePFnP2ZCk6vZZrehknfe54MRfc+17eyxjr7rDmFZGwzrlmItEJ8uuhQIECBd93KIRHwSUFQRAwuC1tYdF9rfCICkjwVyA8jl4qPD1tUql1L6Acfuxq4FV4LH4Jj7jgM/hQeADiwkXiWO+D8KREiovqiia5wuMJKsirb5C9n7TwCKIDg7C5nJyvr5PtOyNZXHzvqZQTngh9EDMTBwCwody3ynN39jxUqNhec4aLBrmKBBCg0fOTQbegRs2uumPsrTvhc15HhGpD+dGAx5gbv0A8v/pd/Or0z1lV+h+abc3d7t8XqLFUs7r8I544/VM2VX/eTnQeyP4Rvxr6e0ZGjva7r1Nw8mbhZ/zx/EqsLhujIwfx3NifypqKAhysz+OXJ8TGoouSRvHLYSskIRCCIPCb45+zv7aIYI2Of025keRg72LYJQj8eM96ioxNpISEyyKoj1ZV8NJxkTT8YdYCEkO9pMVgsfDkZnGRffu4sYzrJ03ce2bTDlqtNkamJHLThFGSscP5ZXyRcxG1SsUTV86RqaRvbDpMc6uZjMRorp4hV2Y27DlHQXkD4SEB3HGFb4Xsk8+P0WIw0y85ioXdJLO1tVnJzIxj1uyu1R2AVW+KCs3iFWOJifMdme4PHnVn3oqxRMX2bt+uUF1az971Yj+gK++f381sBQoUKPh+QiE8Ci4pmFutON1qR1hkcJ8e2/Q1FB5HLxUeDz/o3tImHs/h7F7h+aqEx2NrqzP6UHjchKfch8KTHR2FWqWi2WKhwSTt1aNSqRgVLyaw5dTKCYmH8OyrKsHhI077Mnck9fqyMz7JYXZYAvMTxTlvFGzz+b4ABoWnc12aSF5eyvuIGkv3ao1WreWGtFv42aAnGRg2GIfgYEftlzx5+qd8XLYKg11+Lb4uGm0NbKneyDPnfsuvzzzOF9UbsLospHYgOmOixvmMm/agxWbk16dfYXW5qHpd3W8eT424nwid/MHA4YZ8fnb8XeyCkzkJw/jtiGvQdDr2y7l7WF16EjUqnpt0DcOipIltz53cy/aKAgI0Wv41+yqiA72fx2aLmUe+/ByXIHDVwKEsy5Za6UQrWysZUZH8ZIZU6dh+oYAt5/PRqFQ8dfl8SYiB3enk2TU7ALh2ykgGp0ijk8vqmlm1QyS2P7l6JjqN9PNosdp57VMxieyOKybL1B8AY6uFDz47Is65YWr7Q4fOaGkx8eknRwG47fYZXSYpApw/XUbOkSK0Wg3X3da7OOmK4joOfin2x7nyzpndzO4d1r62HZdLjKLOHNqzBrwKFChQ8H2DUnmo4JKCoUlUd/SBOgKDv37iVUd8PUubO2a6l8W+3YUseRZbzi4sbUHugAWzVZ7CBhDhfj+GNj8KT4Sb8LT4t7SV+1B4AnU6UiMiKGluJq++gdgQqcVwdEISO0qLyKmpgk4P2kdEJ7b34zlZX8m4eOlCa07iQII1OipMzeQ0lksSwTy4q/9cvqw+w86ac+S2VPjsywNwQ9oijjSepaC1nN+eeZU/jvwRkX4aknbEgLCB/HTQL8k1nGdt5acUtOaxteYLdtVtZ0zkeLJD+5Md2p/koH5oVL2zMlqdVqoslRS25nO06TD5rRfbx9SoGRI+jJlxcxgdObZHSVwXDCU8e/4t6qxNBKr1PDroZmZ0aijqwbbq0/zm5EfYBSfT4gbx9Kjr0aql5/9Z6SmeP78TgN+MXsIst+LmwebSizx/SiQOz05eLIkXFwSBn+3YTEWrkYyISH4/Y55k345Wtj92srK1WW08vVEkNHdMHcfgxDjJvqv2nSS/poHI4EB+uFhu6/rn6j04nC4mD0ln2rAM2fiqL45T19RGUmw418wfJRsH+HDtUVrbrGSmxTJ3+mCfcwA+/ugwZrON/v0TmDZ9oN957cd9W7TozVs2kvjE3tnG1rwl9seZOGcIaf0TerVvV7C0WdujqBV1R4ECBf/NUAiPgksKrc2ikhAa0bfqDoDF5Akt6Fm0dEd4CIknZKA7eNaw/nrneKB3K0a+IqU9CA4Sz7fNR7Q0QGSoGLHd1Gr2OZ4QLioA1S3yOOY0N+FpNJlpMVuICJI+ER8UF0tJczNna2uZkp4mGRubINqoDlWWy3rqaNRqZiRn8nnxebaU5ckIT5BWx4KUIawtPcW7hUd8Ep6s0AQWJo1kc9VJ/nxuHa9Pvk+mUgDo1Fp+M+xeHjvxd8pMNTx+8p88M/IhYgOifF6PzhgcPoRBYU9yznCGtRWfUmwq4lDjfg41itHCAeoAMkKyyArpT3xgPGqVBjVq1Cr3D2osLgtV5goq3T/1NqnNT4WKAaGDmBA9ibFR47usz+kIi9PGeyUb+ax8Jy5cJAfF8auhd5MekuRz/ofF+/l77gYEBOYmDOOpUdejU0v/TOyqzuPJY+sAuGvAFG7MGi8ZP9dYw4/3rgfg9sHjuCpbmvr2r5wjbC3OR6/W8OKCywnTex8g1LW28fNNmwG4bdxYxneysv3ty71UthjpFxnOQ7OkUdFVTQZe/EK85o8snd6eMOjB/nPF7U1Gf3L1TBlRrG9u5Z3PxXqbB66d5rPpb31DKx+tFVWbO26c6rcmp7nZxJrV4rxbb5verbpTlFfDgV25qFSqXtfuNNYa2PKJqDhdfVff9sfZ/skh2gxmkjLjGNdF7LYCBf+LMFntaP04J76p11Pw1aEQHgWXFExGcdHe28agPYHdrZDoetEXozN62hXDE3Hr7MKqBhDkTp8yW/x/EXpsOS2t/hQckdDUNrf6HO8XI5Kasvpm2VhoYABJ4WFUGYzk1dYzPl1KTEYnJbElL58TlXLb2oSkFAI0WqrajOQ3NTAgWtr48bL0wXxefJ71Red5fOxsSf0HwB39J7O29BQby87ywyGzyAiVRwf/cNBi9tbmcqaljE9KD7YnuHVGbEAkfxj1ME+eeolycy0/yxFJT3JQnM/5naFSqRgWMYKh4cO5YMzlovE8BW35FLUVYnGauWA8zwWjPEa7K4Rpw0kJ6sfIyNGMi5pAlN53g1R/ONF0gRfzPqDabdObGTeWhwZcR6hW/jDAJbh48eJm3i0S+9ZckzaJx4ZcLiOIR+tLeOTQJzgEF5enjuCnw6VP/WvNrdy9/VNMDjvTkzJ4cvxcyfj+ilL+fEh8jd9Mn8PwOK8a4RIEfrbpCxpNZgbHxfKzmVJb18HCUt4/chKA/1u+gCC993MoCALPrN6O2WZndEYSV02Ukiyr3cGfPhCVoRvmjKZ/irzJ6Ksf78NksTMsO5EFk30rN2++vxeL1c6wQUnMmuJftflg1QEsFjuDBiUyddoAv/M8eN9duzNj/lDSMnt2z3nw6Ru7sNscDB2bzohJXff46Q0EQWDt66L98fI7Z6NWKw54BQo6Yu5Tr6EJkNtevyk4rb7/hivoGf5rCM8zzzzDhg0byMnJQa/X09zc/F2fkoLvIUxGd7BAWN9/CdltbsKj/+Y/Np5wA0+6mz941BuTWR4Z7UGku0lqix8FJy5SJDx1LW0ypQUgNTYSgLIGuW0NYGBCLFUGIxdrGmSEZ0yKO366olJ27ECtjknJ/dhdVsyusmIZ4ZndL5swXQCVJgNHa8uZmCBVcYZEJjIncQA7qvN47cI+/jBuuezc4gMjeGjQIv58bh2vXNzC7PihJARF+nwfKUHx/HnUIzx5+iUqzXX8/OQ/eXrEgz4L+v1BpVIxOHwIg8PFAnWX4Gq3phW2FdBia8aFC5fg/nH/t06tIykwmeSgFJKCUkgOTCFM99UKzw32Nt4oXMO2GlGtiNVH8tCA63z21wGwuRw8dfoTtlSdAuChgYu4NVOugBytL+Gefe9jdtqZkZDNH8Ytl5BQi9PBfTtWU2kykBUezUszV6DrYIWrbjXyo61i3c7Vg4Zx81CpZeyto8fYW1xCoFbLPy5bRoDW+zlrtVh5Yq3Y1PT6cSOYkiVVC7eeymPX+SK0GjW/u2aBTFH595ajlNU1ExsR4rPJaG5xDZ/vOQvAj2+Z7VORKSiuZeO20wA8eIc8DMGD+nojaz8TI8tvv1N+HTujpLCWPe76m5t6qdA0N7Sywd1o9MaH5vdpo9FTey9QkltJQLCehTf1TnVSoECBgu8b/msIj81m49prr2XKlCm8+eab3/XpKPiewkt4+l7hsXkUHn3vo6UFepa65oFW2336GkBQDwhPhNuyZvCr8Ii1NXaHk+ZWM1FhUgUg1a3wlDe24HIJssXgwPgYduUVcbG2XnbsEQkJaNVqatvaqDQYSYmQWrFmpWaKhKe0iLtHSa1RgRoti9IG8knBadYVnZMRHoD7B89gR3Uea0tP8dCQmaQER8rmXJU6kc2VJznZXMKfzq3jb2N/4HdhGB8YzZ9HPcKvT79MUVslvzj5PE+NeICBYek+53cHtUpNSlA/UoL6MSNu9lc6Rk/hElzsqj3G64VraLG3okLFsuQZ3JZxGcFa3w8AWu0Wfn7iXY42FqJRqfn18KtZmiKv7fGQHZPTzrT4LF6cfB36DmRGEAR+eWATJ+oridAH8ubca4jo8OTT5nTy4Jb11JtNDImJ4+kZ0sX5meoa/rZbrGF5cs7s9khzD57dvIvKFiOpURH8fKG0KL/FZOHZz0T15u65E8hOlO5bVtfMW1+I5O+xa2YRGiStwRMEgX+8uxNBEJuMjujvm+C+snIXggCzpw5kxBDf9WAAq94/gM3mYNiwFCZM6F5xWfXmbgRBYNrcIWQO6F39zWdv78FqtjNgRD/GzZT3UPo6WPuGeE0XXD/lG7EIK1Dw347tv7mX8PCe2Yv7AgaDgaQXn/jWXu9Sw3+NRv373/+eH//4x4wY4b/BmwIFHkvb91bh6eETWI+lrS8UnohQj6XNt8Kj02qIdpMcX7a2pMhwtGo1NoeTGh91PAMTRGXmYo2c8ATqdAyJFy06JyorZeOz0jIAsY7HZJe/hysyhwKwoSQXu0t+LUZH92NKXCYOwcUbF/f7fH9qlZpfDl+BTqVhb10uX1af9jnPgyh9OM+O/BGDwtIxOkw8cepFttcc7nFU+LcNl+BiX/1Jfnj8z/z1wn9osbeSHpzEX0Y/ygP9r/FLdgqMNdxx8GWONhYSrNHz3LjbekR2Xp5yPYEaqa3zT8d3sabwLBqVildmrSAzXGq/+8OBnRyvqSRMH8Cri66QBhHYbDz6+QbsLheLBvTnhlHS7/gdFwr59IQYYvDsioXtfaE8+Nvnu6k3msiMj+buuRMlY4Ig8KcPdmBzOJk0OI2F4+Q2tO1H8si5UEGAXstD18/wea2O5BRz+EQxWq2ae2/1n4JWU9PChs9zALjjrlndKi5lxfXs2iJGq998d+/UnTajhfXvivf8jQ/O61N1p6asgYObcgC4/O45fXZcBQouJQQH6L71HwVfHf81hOerwGq1YjAYJD8KLm2YWr95hUev/+a/dDzx1d0pPD0jPOK1aDb69//GR/qv49Fq1KREi0+xfNnaBiaIhCavVt5vB2BMstvW5qOOJzsympSwcGwuJ4cqy2XjUxLTiQ0MoclqZldFoc9zf2CwuEj9pPgENWY5IQMxwOD27NkA/PncOqrMTT7neRCmC+bpEQ8xKnIgZqeVv114l9+d/RfV5u+myagvCILAgfpTPHL8L/zh3JsUt1USrAnkBxnL+OfYnzHERyNRD76ozOGOgy9T0lZPfEA4/5p0L5Ni5bUmPSE7b547wqtnDwLw7JQlTE3KkIyvvXielafFKOjn5i0lPSJSMv7Uth0UNzWTGBbKM4sWSBbuTSYzv1m/FYDbp4yTWSYPXCxhzeGzqFTw+2vnE9ApaGD7iXz2nytGp9XwixvmykiB1ebghVVik9EfLBtPQozcRuhyCby6UqyxWbFkDP2S/IdZvPef/djtTkaPSWfMmO5VwQ/e2o3LJTB51iCyB/kOkvCHLz48hKnVQmp2PJPmDe3Vvt3h87d24nIJjJk1hPRBPbd0KlCgQMH3FZc04Xn22WeJiIho/0lNlVtiFFxa8Cg8QaF9r/A43Elo2q9gaWtHD1UCT/qa3dY14QkJdhMek+8ENpDW8PhLffMQnupG34TBU8dTXCcnCpkxUejUaoxWq8946rHJ4oLpcJmc0KhUKmaligvzrcUFsnGtWs2VWWI61L9zj/s8t4mx6YyNScXmcvLcuR0+5wDcljWLweHJtNhN/PDI2zRYfb9XD4K1gTw1/AF+kLEMrUrD0cZz3Hf0ad4qXIvJ4Vst+zbgcDnZW3eCHx7/M0+fe4PCtgqCNAHckLaItyb+jhvSFsmS1TywOO384cwafnPqIyxOO5Ni+vOfaQ8zKFy+qD1QW8jd3ZCdj/NP8X9HxT5HPx8zi+v6j5SMH6+u5Oc7xdS1h8dOZl5GtmR8zZlzfHrmLGqVir8vW0pkkPdBhSAI/Gbdl9S1msiOjebRudLAiVaLld9+JJKhG6aOZkym1GZmNFv580fi/XDbgvGkJ8iJyn82HKGq3kBcVCi3LJ3g85pt3nGWvKJaQoL13HrdZJ9zAEpLG9i0SQxVuOOO7nvhlBbVsX2TWDfVW3XHZrWz5m2RqF1916w+DRRoM5rZ9I4YLLFcUXcUKFBwieA7JTy/+93vUKlUXf4cPXr0Kx//l7/8JS0tLe0/ZWVlfXj2Cr6PsLqjowODex8d3R1cbrKi6SZi1hc8FjVHF/1yOiKwPX3Nv3IDEO4hM0aLX8tVTEQwKpXYnLTJaPI5JzU+EhDrHXxhgLsu4mKV3Lam12oYmiQ2eDxRJldxpqSloQLO19VR2ypXkJZmizajjQUXsDnlBO/WQWPRqFTsqSriTEO1bFylUvFzd1rY6pIcjjWU+nwPerWWv4y5hcTASEpN9fzw6Nu02HxfDw+0ag03pC3ihXGPMzpyEA7Byafl27j7yP+xqXIfdpf/OPC+hCAI5BqKeSX/E2499GuePf82RW6ic33qQt6e+Dt+kLGMMJ3/WouS1jruPPAKn5UfQYWKu7Pn8tz424nSyxuPbqu8wH37P2gPKPBFdjaV5PL4gU0A3DlkPA8Ml5KBUkMz92xag9XpYH56Nj+eICUsF+vq+fXWLwH44dTJTEyVqjcfHTvN1tx8dGo1f75qsUy9+dPaXVQ1G0mJDueRJfKi+hfW7KWupY3UuEjuXDxRNl5e08y/14u1PT+6cSZBgXLlts1k5V/viOrOrddOITLc//X916tig86pUwcwfET3DTpXvrwNl0tgyqzBDBzqvybIF7Z8coSGGgOxiRHMuWJsr/btDhve3kVri4nUAYlMWjSy+x0UKFCg4L8A32lowcMPP8wNN9zQ5ZyMjIyvfPyAgAACAvq2+aSC7zes7njmgMC+JzyCWx1RfS3C07Vi40FQu3LTNeGJjBAJj9PporXNSpgPZUur1RATEUJ9cxu1ja3ERITI5qTFRQJQUuvb6jUwWbStXays8zk+Ji2ZkxXVHC+rZPmoIZKxmJBgRiQmcKq6ht1FxVwzQpoWNiU5ldigYOrNJvaWFzM3XaoCpIZFcnnGUD4rOssrZw7y0qwV8tePSeXq9NF8WpLD73M2sXrOPWh9PPVOCIrkxQl3ct/h18k3VvPosZW8OOEuQrRdf0+kBSfy9IgHOdJ4ljcLP6PcXMuL+R/ydtE6JseMYHrcaMZEDUKn7lu7Y4W5lp01R9lRe5Qqi5dsRuhCWZI0jRUpswnTyX+fHSEIAhsrT/Dnc+swO21E60N5atR1TIzp73P+v/MP8eypzQjA3KSB/HPiNeg1nXrxVBTyoz3rcAkC1/Ufya/HS2tImi1mbt+wmgaLmeGxCfxzwTI0HX4fBouFB9euw+JwMD0jnYemSMlSfm0Dz34hEo0fz5/OsGRpMf/OswV8dkS0sj1zwyJCOn3ej+eV88keUT351c3zCexUdycIAn99Zzs2u5OJw9JYMNl3wf9/Pj5IY7OJfslRXHP5OJ9zAE4cL+bggXw0GjX33te9KpJ7upx928+jVqu4/aF53c7vCLvNwcf/EpWr6+6bgz6g7/6MW802Vr8iqmbXP7pEiaJWoEDBJYPvlPDExsYSGyvvh6BAwVeF1V3LEhD0DRKer1Ac3NOaHA88tTnmbgiPXqclOEiPyWyjucXkk/AAxEeHugmPkSGZ8iSoNLfdp6y22ef+g5LchKeq3md09djUZFYeOM7xUnkwAcDMzExOVdews7BIRng0ajWX9R/MytPHWZeXKyM8AA8Mn8xnRWfZWJJLoaGRrHB5T5qfDp/Hl5W5XGip4b3CI9zWf5LPc0kLieXF8Xdw3+HXOdtSzmPH3uG58bcRqOn6nlGpVEyMGc7YqCFsrNrLx2VbabQZ2FZ7mG21hwnWBDIpZjjT48YwNDyLMG1wr+4Vs9NKgbGMC8YSLhhLuGgsoc7qJaABaj1TYkcyJ348Y6IGoVF1b62sMDXyx7NrOdSQB8C46Cz+b9T1xAbIa1UcLhfPntrMu4ViE8vrM8by69FLJNHSAEdqyrhv52rsLhfL0gfz7OTFkvdpdTq4b/NaCpsbSQ4N462lVxKi815bp8vFTzZsoripmeTwMP62bIkk3trmcPDTTzdhcTiYmpXG7ZOlCkZjq4nffiwqQ7fNHMe4LKmaYrU7ePo9cfzKacOZMEhuZd5xNI8Dp8Tanp/d5rvgv7yqiY/XHQPg4TvntEfFd4bT6eLVV8R+NcuXjyE1Td4PqiMEQeDNF0RSMW/ZKDKy47uc3xnbPztObWUz0fHhLLpOrlx9HWx+by/NdUYS0mKYfZVvi58CBQoU/DfivyaWurS0lMbGRkpLS3E6neTk5ADQv39/QkPllgwF/5toJzzfgKXN4xj7SoTHo/B0k7rmQXBw92EEHkRGBImEx2AiNcV3c8r46DDOFdZQ66dGJ81taSuva8HhdKHt1EE+Iz4KnUZDm9VGRaOhvRmpB2PTxBqQvNp6DGYL4UFS4jU7K5MXDxxkX0kpDpdLpr5cMWAIK08fZ0tRPm12m2SBDDAoKo75/frzZXk+/zpzkD9NXSp7D9EBITw2fB6/ObGBf57bwZKUocQH+e5lkx2WyPPj7+Chw29yvKmIX5x4n7+MvcVv7UtHaNUalqfMYlnyDM4bithbd4L99SdpsLWwo1ZUYwAC1XoSAmOIC4wiISCa+MBoAjV6TA4LbU4LJocFk/vfOmsjJW1VuDrFl6tRMzZqMLPjxzE5diRBmp4p1g6Xk/eK9/JG/nasLjt6tZa7sudya9ZMWTNRgDaHjZ8c/pSd1SIx+tnw+dw1YIrsXj9RV8md2z/B4nQwOyWLf0y/XKLcCILAL3du4VBlOaE6PW8tvYr4EOn38z/3HWBnYREBWg0vr1hOTLDUJvbHzbvJrakjKjiIP165SBKDLggCT3+6jcZWE/0TYnh4sbyR7JubDlNc00RseDCPXClPXWsz2/j7f3YCcMuy8aT5CSF46a2d2B1OJo7JYMp4//HSW7ecIT+/hpCQAH5w23S/8zw4frCAU8eK0em13NoDNagjnA4nH7wi1kxdc/cs9H2Y2mS3Ofj4BbHe6tqHF6HV/dcsDxQoUKCgW/zXfKP95je/4d///nf7/48ZI8an7tixg9mzZ39HZ6Xg+4Z2wuPDj/914anh+VoKTw8Jj8fS1p3CAxAZHkxldQvNBv+F9PHR4sK/tlFeQwOQEBlGgE6D1e6kqtFAqtvi5oFOoyE7IZrcyjouVNXJCE9saAhpURGUNrVwsryaGQMyJOMjEhOICgqkyWzhRGUlE/pJn8qPjk8kMyKKopYmNhZc5NrB8iaZD4yYwpfl+awuPMOjo6aTFCLvf3Btxlg+KT7BqaZK/u/kJp6fdK3f39fQiH78fdyt/OjoSvbXX+RXJz/k9yOvk9Wq+INGpWZ4RDbDI7K5N/sqzhuK2Fefw4H609RaG7G4bJSYqigxyeua/CFWH8nA8HQGhaUzMCyd/qGpfmOl/eFscxnPnF1DvlGsdxofncUvhq0gLcS3ml5jNnL//lWca6kmQK3lzxNWsDhFnvp1pKaMO7Z/TKvdxsT4frwy60r0Gqnq8dzR/ay+eA6NSsXLi5YzOCZOMv7FhYu8fPAQAH9YtJDhCVK18YuzF3n/iFj4/6crFxEfJiVLG07ksvV0Plq1mmduXCSr68mrqGflZlGhevz6uYSHyK/dG2sOUNfUSkp8BLcv962QHD5RxL7DokXt4bvk6W4emM023npLtN7d8oNpRHTTr0YQBFa+LBKWy6+dQHxSZJfzO2PH+hNUlzUSER3Ckhv9Byh8Fez45BB1FU1ExYcrjUYVKFBwyeG/hvCsXLmSlStXftenoeB7Dg/h0X8DhId2wtP7XXU9TF3zwKPwtLX5T1/zICLcHVzQ0hXhcaewNfiOZlerVaTGR5FfUU9JTZOM8IBYx5NbWceFijrmDZfXf4xJTaa0qYUjJeUywqNRq5mRkcG687lszy+UER6VSsW1g4fz50N7eO/sSa4ZNEy2yBwXl8KkhFQO1ZTx0ukDPD15kfx9qFT8fswyrt3xJlsqc3kz7wB3D5SrAO3nHJ3JX8bewmPH3mFHzVmK97/Ib0dey9CI7ovOpa+rZlhENsMisrk3+2psLjt1liZqLA3UWBuptTRRa2nALjgI1gQRrA0kWBPY/m+kPowBoWnEBER0/2J+UGcx8GbBdtaUHUFAIEIXzKODl7I0eYzfBfvppkoeOvAhNRYj0QHBvDLlBkZHy9/77soi7tu5GrPDzpTENN6Ycw1BWuln7KPc0/zz6AEAnpm5gJmpGZLx87V1/HyTqCDcMW4sVwyV1noV1jfy5FrR6nXP9AnMHCCN1a5obOEPq8XalfsWTGJoPylZcjhdPPWfLThcLuaMymbuGPk9eqG4lg83i2l/P711LoE+IubtdicvuJtuXrV0DBmp/i1qn3x8mIb6VhITI1hxpf8aHw/278jl4rlKAoP0XH9792pQRzjsTj54SSRLV901i8A+tO06nS4+fE4MoLj6wYXfzPenAgUKFHyHUCoSFVxS8Cgoum+gQZengNdftHNX8ChOFneoQncIc6ev2e3ObveJdZOZej/qDUA/t2WtokYeG+1BdpK4sMur8B1MMCI1EYCcEt91OlOy0gDYm1/ic3zhAHEBuuHChXa1rCOuHTwcvUZDTm0VR6oqfB7jx6NEi9L7eTmcb6r1OWdoZBKPj1gAwF/OfMmm8nM+53kwOXYA/xh/GzEBYRS11XHXwVd5NW/r10pg06t1pATHMzZ6CEuSpnFb5mX8bMhtPDH0Lh4ddBP3Zl/FLRlLuarfXBYnTWVyzIivTHZqLS389dx6rtz9V1aXHUZAYGnyGD6e8WOWpYz1SXYEQWBl/kFu3PkWNRYj2WGxfDT7Lp9kZ1NJLndt/xizw86s5CzennutzHK4oeACv9i5BYAHx0zihqHSdK+61jbuXf0ZJrudqWlpPD5bGtvcarXxww/W02azMT4thUfmSEmq3enk8fc2YbRYGZmWKGswCvD25sOcLakhLCiAx3303HE4nDz9xmacLoF5EwcydZTvPkUfrj1CSXkDURHB3H6Df7JcV2fkg1Vi/6G77pmNvpuGxE6Hk7dedNcW3TSZyOjeWbG3fnqUiuJ6IqJDuOzmKb3atzvs33CCisJawqJCWHpb95HaChQoUPDfBoXwKLik4CE8npqZvoRGK35cnM6eRUt3hMeiZulBTQ6ICo/W/XotLV1HJ8fGiAunugb/fWXSEsU6hdLqJr/x1YP6ifajC2V+ktgyxTqdkyVVOHxcgxn9MwA4V11LjUFOvmZnZRKi11NpMHK8Qk6a4oJDuGaQaGX7V85hn+cwOTGNpemDcAkCvz/8pd/38oPsifwgW1wU//zoGk40dB1JPzGmP6umPcLCxJE4BRdvFezg9gOvkGfsuR3t20atpYW/nFvHVbv/xkelB7C5HIyKTOfViXfzu5HXEqn3nd7WaG3j/gMf8OypLdgFFwuSB/Ph7DtJDZHXsnyUf4qHdq9tDyh4fc7VBHZSdrYU5fPIlxtwCQLXDx7BzyZJlQurw8EDn62jymgkMyqKF664TFLDJQgCT67dQkF9I/FhIfzj2mWyGrJXthzkZEkVoYF6/nTzUtl4blktr28QrXKP3zCnva9UR7y78RgXS+oIDw3ksVt9185U1bTw7w9FlerBO2b7DQEBeOP1HVgsdoYP78ecOUP8zvPgi7XHKS+pJyIymGtv7Z1lzGqx894LIqG84cF5BPdhnzFBENprdy6/czbBYX3fw0yBAgUKvmsohEfBJQWnOwVN4ydR6etAo/n6hMfUA4saiBYvTz1AV1Y1gDh3d/jaLghPSkIEKhUYTVaajb6PNzC1a8LTPzGGsMAATFY7edXyfjwxocGMcMcH780vlo0H6nQscqs8687n+nyNe0aNRwVsKynkYqP8NQB+OW4OARotB2tK+aL0gs85KpWKX45cyJzEgdhcTh448CGlrY0+53oQqQ/m6dE38IfRNxKhCybPWMVt+1/m7YKdWJw9U+a+DRQYq/nzubVcueuvfFx6UCQ6Uem8OOFOXpt0L2Oj/RfYH6or5optr7GzOg+9WsNvRy/lhUnXEqaTL3LfOn+En+/fKBKZ/iN5fsZyWc3OjpJCHtqyDofLxZUDh/KHWQskyopLEPjFF5vJqaoiIjCA169eQUSg9LXe2n+Mzefy0KnV/PO6y4gLkxK1AxdLeGO7SIB/d+0CWf2Y1e7gNyu/wOFyMW9Mf5ZMGCx7L8WVjbz5mUhkfnLLbJ/R7AD/fH0bVpuDMcNTWThbXsfkwblzFXy59SwADz48v9u6PovZxrv/2gnATXfPIqSXhGX9u/toqDEQnxzJ0hv7Vt05vf8iF08Uow/UKY1GFShQcMlCITwKLil8swqPeExXD5uHdkRHhcefKtEZ4e4eO4ZuFJ54N+Gpq/dPeAL1OhJjxCL/0mrfvXY8Ck9pXRMmHw1PNWo1ozKSADhe5NtyNmugaBPamVfkc/zyIeJidGPuBawOuWUsMzKKxVkDAHgt54jPY6SGRnLfMFG9efrodiwO32REo1Lz94lXMSwyiSabiXv2r6LJ2vW1BJifOIIPpj/CzPghOAQnr+Rt4fKdf+Lli1uotfi3BH6TaLaZ+KjkALfuf4kb9z3PJ6WHsAtOxkRl8NKEu3ht4r1MjOnvd+HtcLn457kd3LbnHWotRrLCYvl4zt3clDVeto9LEPjjsZ08dUSsF7l76AT+OGWJJI0NYF95Cfdtdqs/2QP5y5zFsjl/3rWb9ecvoFWreWH55WRESVWkA4Wl/O3LvQA8sWQ2Y1KTJeMNRhNPrPoCQYBrJo9g0aiBsvf28rr95Fc2EB0WzBM3yiOmnS4Xz7yxBZvdyZSRGSye6luN2Xson/1HCtBo1Pz4/gV+r6XLJfCy25q2aPEIBg1K8jmvIz59dz+NDa0kpUSx7Jrx3c7viDajhY9eFWuKbnl0UZ/23QH45EVROVpww1Qi4+RBIAoUKFBwKUAhPAouKThs4iJaq//mLG097aXTEUHBYpywyyVgs/asNqTHCk+sm/A0+K/hAUjtYGvzhZjwEGIjQhAEyKv0ra6MyRAXpCeKfNfxzHIXmu8vKMXm4zpNTU8jITSUZouF7QWFPo9x32iRzKzNO09Vq28Sd/+wySQFh1HRZuCF0/t9zgEI1up5dcoNJAdFUNzawEMHP8Tq7P76xwSE8Zcxt/C7EdeSFBhJi93EysKdXLHrL/z65Iecaynv9hhfF1annT21ufzixHss3fEsfz2/nlxDBVqVhjkJw3h5wl28OvEeJsRkd6kwXGip4ZbdK3k5dw8CiA1a59zN4Ah5P6Y2u437dq7m1bNibcpjo2fw5Dh5PcyhyjLu2rQGm9PJgoz+PDdvmSxq/O2jx3njiNjH5tlFC5maniYZr2w28JNPRAXpytFDuWG8tO7H5RJ48oPN1BvFCOqfL58lO98jF8p4d5v4Gr/5wQKiwuQpaZ9+eZJTeZUEB+r45Z2+iYzZYuP5N0SCd8OKCV0GFWzbdpbz5ysJCtJz192z/c7zoLmxlY/f2QfA7Q/NQ9fLuOd1/9mHsdlEanY8c68Y2/0OvUBxbiWHt55GpVJx1QPz+/TYChQoUPB9wn9NSpsCBT2Bh4xov0FL21chPB1jss0ma49isz3pa83NXasSHkubsdWC2WIjKNB3elNaYiSHz5RQWuWb8ICo8tS3tJFbWsuorGTZ+JjMFEBUeHw1IB2WlEBMSDANbSaOlVa0Bxl4oFGruXLYUF49dJiPT59hySD5E/vRCUlMTk7lYGUZr+Uc4bfT58rmBOv0/GbCPB7Y9RmvnjnIrOQsJibIG0wCxAeF8a+pN3Ljrrc51lDGI4c+4a8TriRU13VPG5VKxdKUMSxMGsme2vOsKtlPTlMxm6tOsrnqJIPDU5gSO4DhkakMi0glOuDr9QNrdVg43VTKiaYiTjQVc665HLvgvdcGhSdzWfJYFiWP8luf0xFtDhsvnd/Fv/MP4RBchGj1PDXmMi5LlUd+A5S1NnPPjk/JbapDr9bwl6lLuSJrmGzeseoK7ty4GovDwey0TF5ceBm6Tla39edzeWbHTgB+OnM6Vw6X2sParDYe/mA9TSYzQ5Pi+e0yuTKzctdR9l0oJkCr4S8/WEpQp0S1ljYLv/33ZgQBrpo+gpkj5Fa+itpmXv5IVJAevn4mCTG++zL9+8MDVNcaSIgL59br/Mc9m0xW3nhNfF833TyFmJjuf+fvvrYTs8nGgCHJzFwgv55dodVgZvWbYuz1TQ/Pb/8O6it84q7dmXbZGFKy5QRYgQIFCi4VKIRHwSUFwZ2gplb3vXjpsZLYbb1P79Jo1ASHBGBqs9JqtPQooSk6WlzUNnaRvgYQEqwnNCSA1jYrVTUtZKXH+ZyXmSI+tc4v863eAAxNT2Df2WJOF1Vx/ezRsvERaYkEaDXUGdrIq25gYJK0t4tarWLOwCw+OXGGTWcvyggPwDUjhvGvQ4fZXVRMfkMD/WPkT9MfGjuJg5VlvHs2h9tHjCU9IlI2Z0n6YK7MGsaawrM8uGsN65fd7rM3D8DAiHhenHwt9+xfxY7qi1yz4w1enHwd/cN9X6uO0Ko1zEkczpzE4eS2VPBByX62VJ0i11BBrsFr7UsOimJ4ZCrDI1L/n72zjI7q7NrwNRN3dydY0ASCa3B3t9ICLYUWLW0pUgoUK6VIW6y4u7sTXBMkxN3dfWa+H0N4aTOTTALp19JzrZWVdnjkjCR57rP3vjdWOsboqmmio6aFrromOmqa6KprUiApJqkgk6T8zLe+ZxGWnUBgZunGo+ZaBnS2bkBPu0bUNCw/dQrkReiXYwP48dl54vLkNuSdbWszt0E3rHUVvz73EyL5/PoxUgvyMNfWY5PXABpZ2JUadycmkgnnjpFTVEQrO0c2dO2Dltqf/4zcCA1j1tnzAIz2cOezpk3+9O8SqZSZR87iF5+Iqa4Oa4f0QvsvUY+HwVGsOSuPinzTrz3Vrf/8OZPJZCzcfYn4tCwcLIyZMbC0s5hUKmPRpgvkFRThUcuO/h0alBoDEBAcz4Hj8vTJKRM6KL1hALBj+y2Sk7OwsTFm0GDFPXzeJiwogTNH5I1ox0/tUuHfS4c3XSc7Iw/H6la06dGwQnPLIyoonquH5JG8wV92e69rCwgICPzTEASPwAeFqvUxlUHrdd+LgrzKFbAbGOmQm1NAZjkpaiWYv86nT0pSXpsD8kiEva0J/kHxRMemKRU8NR0tAQiMUGznDODuKj/k+oYoTlnT1lCnaXVHvP3DuPkqtJTgAehZvxaHn77gwstA5nb3QvMv9VTOJiZ0rlGdi0HBbH30mCVdu5Rao42DM20dnLkZFc6yezdY37Wvwuv5sVlXXqUl4p+WxMTrxzjQbSTaaop/rbWwrMbuth8x9f5hwrJTGHztD35s3Ice9qrfda9tZMeCBoOZVrsH1xJe8iI9ihfpkYTlJBGbl0ZsXhoX456pvN5fsdMxxcPUGXcTZzxMXLDXNa1Qo9uonDQW+57nenyQfD1dY+Y17IaXTelIWgl7A32Yf/8ixTIp9Uyt2OQ1EFsFwvFsSADTLp+lUCqhlZ0jf3TvX8qx7XF0DJNPnKJYKqW3Wy3mdfQqdf1Lz9/gemAYWupq/D68L/YmfzYhSMrMZtYeeapbn8ZuDGpWv9S1HLr5jGs+wairiVk6rge6CkTK/gtPeBoQg46WBvM+7YpYXPp1LCqSsGzdeSRSGR1a16ZNsxpKX6eQkESOHpELoy+ndinXhlomk7F+5TmkUhmtO9bBvYliG2xlpCRkcHy7NwBjZ3Z779GdPT+dRiqV0axrA2o1cn6vawsICAj80xAEj8AHSUUOiapSkoZWWcFjaKRLQmw6meWkqJVgaSlPv0kuR/AA2Nu8FjxlpKtVdzRHJILk9BxSMnIUOlXVd7FGLBIRk5JJUno2Fgrsfdu6ueDtH4b3q3CF/VCaOttjoa9LUnYut0Mi8KpVOtVofBNPLgYFc+zlK6a3aoWFfulrmdOiHbeiIzgXGsSD2Gia2pbuEaOrocnm9gPpfWY7vilxzL13gZ9a9lD6/rub2nOswwSmPzjCvaRwpj84gk9qNLPqdUJDrHoapLGmHv0dmtLfQf78s4ry8MuI5kVGFK8yYkgrzCGvuJA8SSF5kgJyJYXkS4pQF6lhrmWAhbYhFq+/m2sZYqtjQkMTJyy1K9eLJyEvk82BdzgQ9phCqQQNkZhxNVsysVabUg1CS8gtKmTRoyvsC/IFoKdTbVa26qlw/O6XPsy7eRkZ0M2lBqs79URb/c9/PvwTk5hw9Dj5xcW0c3FmRfduiP/yPuy895TdD3wAWN6/G+4Of45aFRYXM33HaVKycqlhY87cgaVT3QKjk1h1WJ7mNbV/G+o4lU7FCo1OZv0heSrbtJHtsHvdh+qv7D16n5DwJIwMdJj2aUeFY0AeLVr9y3mkUhlt2taiWTNXpWNLuHX1Fb6PwtDUUmfCtNKivjz2/nqZgvwi6jRyonmniqXClUf4qxhuHJOLtzHfKr6ZICAgIPAhIQgegQ+KKgzwoF3BXjp/pcR1LavCEZ7Mcsfa2xgDEB2brnSMrrYmjtYmRMSlERiRSIsGpe846+toUdPeAv+oRHxCYuncuHRkoI2bMxwD34hYMnLzMdL9s8WumlhM97q12Hn/KSefvVIoeBrZ2eJha8PT2Dh2+/gwvXXpviS1zCwY6laffX7P+PHudY4NGFnqAA3gYGDMr237MebKAQ6HPKe+mTUf1Vbe9d5US48trUaxxu8amwJvsyP4Pi/SYlnddBCWOoprPMrDQEOHZuY1aGauPEIgkUkRAWLR+7tT/1ehA9Dcwpn5DbvjWka63ouUeKZ4nyQ0U27V/ZV7WybXb1FKXMhkMtY8usvqR3JjiBF1GrKoTcdSbmwhKamMPXSEzIICGtvZ8mvf3qXqeq76h7D0/HX5fp1a063unz9bMpmMJceu4RsRh4GOFms+6l2qbic3v5Bv/zhDYbGENvVdGNHBo9RzKy6WsGDj+TeubH3bl44QAYRFJrPjoNyqesqEDhgblTY8KOH8uWf4vYxBR0eTyV+UX9xfWFDEH2vk7meDRrfC2rZ0j6OyiA5L4vxBuRX3x7OUC/jKsmv5SWQyGa37NMK1vuLaNwEBAYEPCcGlTeDDokTxvP8AD1raJSltlRM8Bq8PVOXZTJdgYfHafS0pq9xUPfvXB6qyIjwANZ1K0toU99oBaOgqNyvwCVFsPW1naoSrlSkSqYy7gREKx/RtKLf+veIfQkZevsIx45vI7Xn3PPUlt1Bx1GxGk1boaWjgmxjPwVfPlV5za1tnvmss7yGy8OFl7sVHKh0LoC4WM7NeR35rPgR9dS0ep0TR58pG9oY+okhacVMKVVATid+b2EnIy2Kx73k6XVjHrpAHFEolNDZzYHvr0WxvPVqp2JHKZGx+eZ/+53YSmpmKlY4+ezoP44sGLRXaOc/3vvJG7Exp3IIf23ZSKHZGHThEcm4ubhYWbB7QDx2NPwuVF7EJzDxyFhkwuFE9xrUqbc186O4zjtx/gVgk4qdRPXAwNy41ZvnBa4QnpGFprM+CMV0VCoGtJ+4TEJ6Iob42cyd0UThGIpGybO15ioultGziSqe2yhuHZmTksnmT3Bb6o7FtsFDBuvn4/vvEx6RhZmHA0LGtyx3/V3auOo9UIqWplxv1mijvq1QZgnwjuH36KSKRiFFf93mvawsICAj8UxEEj8AHSZWktOm8TmnLr2RKm7FqfXVKKHGAKiqSkJlZdlTI3ua14IktT/DID8Jl1/G8tp4OVlzHA9Cmtjw6dPOV4n47dWwsqWlpTqFEwrkXipuDdqruiqOxEen5+Rx+8ULhGAtdPaZ5tgTgx7s3lNpUA4xza0I/l7pIZDIm3zxORFbZrwVAJ9vaHOkwnpqGlqQV5vKDz1l6Xd7AqajnSGQV77dUlUhlMm4nhDDjwRE6Xlj7Rug0MnNge+tR7Gk7lhaWLko/+wm5WXx0+QA/Pr5GkVRKF4canO89jlY2zqXG5hcX8+Wl0+x66YMIWNSmIzOatiq1dnBKCqMOHCIpJ4faFubsGDIIw780Fo1Nz+TzvSfIKyqmZTVH5vcsbXP9JCyGpSeuAzCleyta1Sp9TafuvuTUXT/EIhE/ftwdE32dUmNehsSx/eR9AL7+qCPmClIyAQ6desyroDj0dDWZ+bnynjsAWzbfIDMzDxcXC/oPUB45LCEtJZt9W24C8PEXndDWUW6CoIiAZ1F4n3uGSCRi7FfdKzRXFXYtOwlA+wFNcK5d2olRQEBA4ENEEDwCHxavDy4lbm3vk5JeOrnZiiMW5WFkLK9TSU/JUWm8pqb6G6e2+PiyG1462JkCkJyaTXZOgdJxtZ3l9Q4vQ+KVjmlUXW5cEBCdSFq2YqHVto78rvP1l6EUKmggKhKJGOAhrzvY88BXYYRKTSxmnKf8Tv/6ew+URnk+btCYhpbWZBUWMOXSaYqlioWISCRiaYtu1DO1IiU/l0Hnd/MiRfnzLMFZ34yjHSYwr2E3TDR1Cc9O4auHx+h5aT0nIp8p3e/vIjonnXV+1+l4fi2f3N7DmeiXFL0ldPa2HUsLy2pKD+0ymYyzEf50PbkF77hwtNXUWdK8GxvbD8BEu7RoiMvOYuiJ/ZwNDURDLGZd516Mrlc6dSwgKYkR+w++ETs7hwzGVPfP66Vk5zJ+9zGSsnOoYWHGmiGlLayjUtKZtv0UxRIpXRvW5BOv0tEf/6hEluyT98n5tGdzGtcsXc+VnVfA/N/PIpHK6NSsFp2b11L4eoRHpfDHbrkZwOSPvd7YuivC1yeSM2d8AJgyratKDY3/WHOR3JwCataxpWMPxc5wypDJZGz6US5IOvRrhIsKTU0rgt/DEB5ceo5YTczIWb3f69oCAgIC/2QEwSPwQVHSHFRaBYdUPUP5neuccqItyjB7naKWmly+CUEJtnbyyE1MdGqZ4wz0tbF6nWoTEq48Xa2uqw1ikYi45EwSUhVfh4WxPjXszJHJ4J6f4pS1Ri62WBrqkZVfgLd/uMIxA9zroKupQVBSCrdDFKeYDW5QDwcjI5Jyctj66LHCMepiMWs69URfQ5OH8TGsfHBL6fPTUddga4fB1Da2ICkvhyEX9nAlOljp+BI0xGqMcm3K5a5fMq2OF8aaOoRlp/D1o+N0v/Qbq19e43labJW6AJYgk8kIyUpmd8gDxnrvouOFtfzqf5PYvAwMNbQZUc2TI17jyxU6AOGZaYy9cohJN46TXphPXVMrTvf6mBE13RXOexAbTe/Du/BNjMdYS5sdvQbRq3rtUuNeJiQy6sAhUnPzqGtlya6hpcVOZl4+43cfJTQ5FWtDfTaN6o+B9p97H2XnF/Dl1hOk5eRRx96SRUNLp6Bl5OTz1cZTFBRJaF3PhfHdmyl8rj/tuEp0YgY25oZ8+7FiA4JiiZQla85SWCShWSMXenZWXN8DUFBQxM8rzwLQq7cHDRqUX+vy/Ek4l8/4IhKJmPxNzwrbUN8864vf43C0dDT4aMb7t4reveIUAJ2GtcC+utB3R0BA4L+DIHgEPijUXt89lhS/f8Gj/7oRaE5W5SI8JYInpQKCx/515CYmpvz0LFdnebpacLjydDU9HU1qvE5rexaoPGWtdT15ytqtl4pT1tTEYrq5y++gn3uqOGXNUEebga+jPDvuPVE4RlNNjZlt5IYFmx88JCVHcbqfs5EJK7y6ArDh6QOuRoQovXZLXX0OdhtJGxtncouLmHDtCLsCFO//V/Q1tPi8dhuudJ3CjLodMNbUITInjfUB3gy69gftzq1mwdOzeCcEvzEJeB8k5mVxIvIZ3z46Qbtzq+lx6XcW+Z7nbpL89W9p6cLPTQbg3WM637v3oJ6JbZlCJ7+4iF98vOly8g9uxIaiKVbjy/otOdZ9DNWNSvc9kslk7HzxlBGnDpKcl0ttMwtODRpFS7vSfZR84+IYfeAQaXn5NLSxZteQQZjo/Fns5BQUMmHPcV7FJ2Gmp8u2MYOwMfpzJKVYImXW7rOEJKRiaajH2o/7ljIpkEilfLf1LLEpmdibG7F4bDeF9tJnb/lx/vYr1MQiFn7eAwM97VJjAPYeuY9/UDz6elp8/YXiGqASdmy/RUxMGmbm+kz4tL3ScW+eT5GEdcvOANC9fyNq1ysdhSqLgvwiti6Xzx/8qRcWr41I3hevHoXy5Jofaupihk/v8V7XFhAQEPinI7i0CXxQlER4JMXvv/Bc10B+iCosKKaosBiNcvpw/JU3gkcFm+kS/hfhKV/wVHex5M7DEELClEd4ABrWtCMgPBHfwBilaT8t6zqz7cJD7vpFIJFKSxWqA/RoVJudN59w/WUIOfmF6CnohTKmmQe77/vgHRxOcGIK1S1LH7Z71K7FHw8f8yIhgV/v3uP7Th0UXlMP11p8VC+aHS+eMuPKOc4OGYOtvuICckNNbbZ2HMycexc4GPyMefcvEpWVzreNvRQ6vf0VfQ0tPqvVWh71ifXnSlwA3vHBJORnsS/sEfvCHqGrrkkNAwsc9U1x1DP533c9E3TVNZHKZPIvXn+XSUkpyCEiO5WInFT599dfCfl//kxoitVobOZIS0sXetjXw17PuNxrLuFadAjfP7hEZHY6AG1snPmhWReqGZoqHJ9fXMw878sc8pfXUfWuXpvl7bugq1H6/bwbGcnnx06SXVhII1tbtgzqj4HWn6M2BUXFTN5/Et/oOIy0tdg6egAu5n92KZPJZKw4eYNb/uFoa6iz9pO+WBmVrrfZePoed/0i0NZQZ+VnvTFUIGQi49JYsV2e7jaufwsa1FRclxIUmsD2A3IDhmmfdiwzlS0wII5DB+W1QNOmd0NfX7GAepvj++8REZKIoZEuH08u38ntr5zY7k1ibDoWNsYMHN+uwvPLY89P8uhOx6EtsHEuv+GugICAwIeEIHgEPij+J3jef4RH961DT05WPsZmiguilWFmKT+cp6fmUFwkQV2j/HoAe/vXZgQxZae0AVRXIcID0LCmLQcvPi0zwtOgmg36OlqkZ+fhF5FAfZfStQR17CxxtjAhPCmNKy+C6eNZp9QYB1NjOtWuziX/YHbce8KiPp1LjRGLRHzTrg2jDx5mn+8zhrs3oKZ56YamAN+1bMeThFieJyXwxcXTHOg7tFRNSAkaYjWWt+iOo74xK31ussnvAdE5Gaxq1atUw0xl6Klr0texAX0dG1AgKeZeUhhXYgO4GhdIUkE2vmkx+KYpdrOrCCKgjrENLS1daGlZjUZmDmirqXaNJfinJfKzjzeXouRNR611DZjn2ZEeTrWURjLisrOYeOEEvonxiEUivm3elgkNPRWOP/XKn6/PXaBIIqGpgz2bB/RDT/PPoqhIImHaoTPcC4tCV1ODzaMGUMu69OF6+/XH7LvtA8CPw7pS1750etUN3xD+OCcXHXNHdaKmfel1CgqL+e7X0+QVFNHIzZ6xfUr3hQIoLCpmyZpzFBdLadO8Bp3blf6sllBcLGHlT2eRSmV4dXCjZUvlVuMlJCdmsnvTdQDGTemEobFyi2tFpKdkc2DDaye4Gd0qbHRQHv6PQ3l05SViNSG6IyDwvsgrKEKjoHImRpXdT6DyCIJH4INC7XVRsUTy/iM8ampidPS0yMspILcSgsfQSAd1dTWKiyWkJmdhqULKip29/K58bAVS2sIikpFIpEo7szesKTclCIpMIjuvAH0drVJjNNTUaOHmyKUnQdx+Ga5Q8IhEInp41Ob3i3c5+dhPoeABGNuiEZf8gznh+4rpHVthqlf6MNjCyZFO1V25HBzC95eusGfYEIWRGC01dX7r0pueh3bxJCGWFfe9mdOyvdLXRCQS8UWDltjrGzHrzhnORgQQlZ3B0ubdqGdmrXSeIrTU1GlnXYN21jVYIJMRlJlIeHYqkTmpRGanEZGTSlR2GnF5GSir9DHS0MZJ3xRHfVOc9eTfnfRNcdE3w0iztIGAKvinJbL22W3ORshTC9VFYj5x82RKw1boa5R+b0s4ExLAdzcukVGQj7GWNus696KNg3OpcTKZjD8ePmL5DXmhf7eaNfi5Z3e0/tJ4VCKV8s2xC1wLDEVLXY0NI/rRwL70a3z2qT+rzsjXmtWnHV0alu71FJGQxrzt5wEY7uVOj6aKbaPX7L1BUGQSJgY6LPy8h8JIJMCO/XflDUYNdfiqHFe2A/vvExKSiIGhNpO/KC3QFbFx1Xnycgtxa+BAlz6lDR7KY99vl8nNzse1jh1efSs+vzz2/HQagI5DmgvRHQGB90SXbzehpll+9Pd9ISmsXDq9gBxB8Ah8UJQInuLCqumlomegTV5OAdlZFTcuEIvFmFkYkBCXTlJCpmqC53VKW0ZGHhkZuRiV0RzRzsYEHW0N8vKLiIhOoZqT4oONhYk+dpZGxCRm4BMQQ2t3xX0+WtVz4dKTIK75BDOxVwuFY/p4uvH7xbvcD4oiIikNJ4vSDRYbOdpS39aK57EJbL3zmK86t1G41rwOXtyOiOBhdAw7Hj/lY89GCsc5Ghrzk1dXJl44yWbfR9gZGDK2vuKxJfSrVhdrXQM+u36U5ynx9D6znRE1PfjKva1Cp7LyEItE1DKyopZR6chEoVRCsVSCWCRCLBIjRoSaSPTerdL/KnREQA+n2kxv2JrqxoojZACZBQV8f+sKxwL9AKhvYcVvXXrjaGhcamyxVMrCK9fY6+MLwNjGHnzn1b6UGJVIpXx34iJnXwTInd2G9qapc+kaljsBEczZfwGAUW08GNO29PuWlVfA9A0nyc4vxKO6HdMGtlX4PM7ffsWRK/LrWjCxOxYmim9A+LyMYs9ReaRo5uedMXntlqiI8LAkdu2Um2JMntwJExPlY0t4eDuIm5deIhaL+PLbihsVRAQlcGavvAHquErML4/ndwJ5ePmFEN0REBD4TyMIHoEPCk0teRpQYRWFfg1N9EiOzyAjVTVr6b9iZWtMQlw68bFp1HUvXRD+V3R0NLGxMSYuLp2wsCTc3Z2UjhWLRbjVtOHJs0heBsQqFTwATes5cezqM+4/C1cqeNo3cEVdTUxQTDKhcSlUsyldf2NnakSb2i54+4ex77YP3/bzKjVGJBIxuX1zJu49wa77TxndzAMrw9KHUzsjQ75t147vL19hxU1vWjg6UNtS8XPoVq0mUxo3Z+3jeyy4dZW84iI+91Ds3lVCc2tHLvYZx+JHVzkV/oo9gU85E/6KmR5tGVHDXWl0oKJoitXQFJefrlgZZDIZ9xIi2en/hHORfxY6Uxq0opZJ2Xfv78VGMfPKWWKysxCLREzyaMZUzxYK0wJzCguZduoM10LDEAGzvdrxiWfpPjSFxRK+PnqO835BqIlE/DyoB21ruJQa9zwynmk75PbT3dxr8lXv0kKmSCLhm82nCY9PxcpEn+Xjeyq8tuCoJJZuvQTAx32b0byBs8Lnm5Wdz+JVZ5BKZXTvUI/2LRXXrIG8GemK5acpKpLQrLkrnTrXUzq2hPy8QtYtk0dP+g1vjmsFbaRlMhkbFh1HUiylRae6eKiQPlcRpFIpm+YfAqD76DbYVrN8r+sLCPyXubjsUwwNy29E/L7IzMzEeut3f9t+HxqCS5vAB4WmtlzDF+QXVsn6Rq/74mRWUvDYvK7JiVPBhKAEl2ryQ2xoSNm1OQB1a8kLtl+8Ul6fA9C8vlw43Xuu2HYawFBPm5Z1nAE4/1CxExvI79QDHH/oR3a+4h5A7Wq40MjBloJiCb/fuKd0rRHuDfByrUaRRML0M2fJL1IuXKc3acUXjZoDsPyeN6se3CrXNtpK14B1bfuyv8sIahtbkF6Yz7z7F+l9Zjv34iP/FtvpypCUl8P6F/fwOr6J4Rf3cS4yABHQ06k253uP47d2/coUOwWSYpbcuc7wEweIyc7CydCYQ/2G81Wz1goFRUJ2NiP2H+RaaBha6mqs69NLodjJLyrmywOnOO8XhIZYzC+De9KlTulDe2hiKpP+OEZeYREtajqyZFi3UgJTJpOx4sA17r2KRFtTnVUT+2BuVDrCkp1bwDdrTpFfWEyz+k5MGKA4+iiTyVj5+0USk7OwszFm6gTFVtUl7N93j4CAePT1tZkxs7tKEbk9m2+QEJuOhZURYyaWFvvlcev8c3zuBKOhqc6E795/X5wbRx8S5BOBjp4Wo74W+u4ICLxPdLQ0/vYvgcojCB6BDwrN105hhXlVE+EpETwZqdmVmm/9OkUtXoWanBKqvb4rGxpatvsaQL3a8vqclwFlCx7POo6oiUVExqcRm6S8qWm3JvI74ucf+isVAy1qOuJiaUpOQSEnHvopHCMSiZjRSW4/feTpSyJS0pWOW9a1C+a6ugQlp7ypG1E29qtmrZnVTJ4it/bxPX68e10l0dLc2pHTvT5mQZNOGGpq4ZeWyLCLe+l+aivbXz0io+D/P1e6WCrlRkwon18/RovDv7H8yXXCs9LQU9dkeA13lYQOwJ2YSHod2sUm30fIgOFuDTg7ZAyNrRW7md2PiqLvjt28TEjEREeHXUMG061W6Tqb7IJCPttznBtBYWirq/P7iL4KxU58ehafbTpKem4+9Rys+GVMbzQUNPDcc/UpR7yfIxLB0k964OZYOl1QJpOxcNN5ohPSsTYzKLNu5/SlZ1y7HYCampj5M3uhq6vcCCA0NJGdO+SftS++7IS5uXIHtxLCghI4slvu+vbFtz3fNCZWlfy8QjYvkTunDf60PTaOpSOo70JhfhHbFh8DYOi07phY/n13ogUEBAT+aQiCR+CDQkv7dUpbflUJHnkqVmVT2mxe99WJq4jgcS0RPKpEeOQpNZExqaRnKu5pA6Cvq0W96vIDb1lRnnYNXNHWVCc6OYOXEQkKx4hEIka2dgdg720fpFLFgsPTyZ621Z0plkpZc/W20j3N9HRZ3kPec2fXUx+uh4YqHQswuVEzvm8lt7L+w/cxc29eRqqC6FEXixnr5sm1fp8xoqY7Wmrq+KcnseDhZZoe/pXpt05xP+Hvjfok5mZzMPgZk28cp9HBNXx05SDnIgMolklxN7dleYvuPBj8BUtbdCtX6MRnZ/HFpVOMOHmQoLQUzHV02dytH0vbd0FPgeW0TCZj66PHjDlwmOTcXGqZm3N45HAa2ZUWRhl5+YzbeYT74VHoaWryx+j+tKnuXGpcclYOn246Snx6Fs4WJvw2rp9C+/LrviH8cuQGANMHtqNdQ1eFz2nXmYfceByChroaS6f0xthAcf1VeGQyazdfBeDTUW1wq6E81ay4WMKKZWcoLpbSsmUNlVLZpFIpa5acQiKR0srLjeZtlafKKePghqskxaVjaWvM4M8qHh0qjxObrpAYnYq5rQn9Pis7uiUgICDwoSPU8Ah8UGi+tnOtqhqe/0V4Kit4KhPhkR9sw8OSynRfAzA00MHJ3oyI6BT8AuJo2UTxwRHkaW2+gTHcexbGgA4NFI7R0dKgXQNXLjwK4PxDf+o5K3Y2693YjTVnbxOZnM4t/zDa1lFcFzS9Yyu8g8M5+zKQkU3daexkp3BcOxcXxjb2YPvjp3xz7iJnxo7GXE95AfnHDRqhq6HBt9cvsMfPl7ziIlZ4dUNdhbocM21dljTvxjce7TkW+oL9Qb74pydxLPQlx0Jf4mxgQksbJzwt7PGwsMXZwOS9GBDIZDJiczIJTE/mUVI016JD8Ev7s6g10dKhr0sdhtVoSG0T1eovCiUStj17zJpHd8ktLkIsEjGqbkNmNm2NkZZiR6GcwkJmn7/I2YBAAPq41WZxl87oapZOoUjOzmHcrqMEJCRjpKPNH6P6U9+u9OciLSePCRuPEJaYipWRPhsnDMBUv7TpxqvIBL7behaZDAa3bcDIDopdyu4/j2D9QblQnjnaizrVFH8WCwqLWbDyFAWFxTRxd2ZovyaKX6jX7Nt7l6CgeAwMtJk2o5tK7+3540949SwKHV1NPp/VvdzxfyU2IpnDm+UC79M5fd67DXVGShb7fjkLwNg5/dCuYPRJQEBA4ENDEDwCHxQlEZ6C3Kqt4UlPqWRK2+sanuTETPLzClU66NjamqClpU5BQTExMWk4lpP6Uq+2LRHRKfj6RZcteBo4s/HIHR6+jKKgsBgtJY1UuzWpxYVHAVx4FMDUAW0U1nzoamkyoFk9dtx4zJZrj2jj5qLw4OhmY8ngxvU5+Pg535++zJFPR6KloXjfWW3bcCciksDkFKaeOsP2wQOV9twBGOpWH211dWZcOcvRQD+iMjNY2aE7TkbGSue8jZGWNmPdPPmodmN8kuM4EOTLyXA/wrPSCM9KY2+gDwDGmtq4W9jS0MwGWz1DjLV0MNXSwURbFxMtHYw1tZHIZOQUFZJdVEBWUQHZRYVkFRUQnZ1BQHoSAWlJBKYnk1VUuuapoZkN7eyq0d6uGg3NbFQ2U5DJZHhHR/DDrauEpMv7NjW2tmVhm07UNVculoJTUph84hQhKamoi8V859WO0R7uCt+/yNR0Juw+RkRqOhb6umwZPZCaVqUd4dJy8hi/4TDB8SlYGOqx9fPB2JqWTqmKTclk6m/HyS8spkUdJ2YN8VK8b1wac349jVQmo3fbuvTzqq/0+az94wqhEcmYGOny3bTuiMXKBUxgQBy7dspF1JdTumCmgtV8cmImf6yRGyaM+bwDFlZG5c55G5lMxsbFJykqLMajVQ1adik/olRR9v58htysfFzrO9BhcNlmHgICAgL/BQTBI/BBofO6OWhudtXUYJhayg83qYmZlZpvZKyLgZEOWRl5REekUL12+a5OampiatSw5sWLaPxfxZYreDzqO3Lm8nMe+ypPVQOo7WyFhYk+SWnZ3H8RQdtGisVRy7rOmBnqkpKZyw3fEDo1Kl3PAXLzgn23fXgSFsPdoEha1lTsKDe9Yyuu+ocQnJTKuut3ldpUa6mrs6Z3Lwbt3sv9qGhmnjnHL72U12wA9K3hhp6GJlMvn+ZhfAzdDm5ndot2jKrrrrCvjyJEIhEeFrZ4WNgyt0kHbsWF8ygxmqdJsTxPiSe9MJ/rMaFcjyk71U4V1EViqhmZUtfUijY2LrS1dcFcp3wr5LeRyWTcjY1i9cM7PIiLBsBcR5dvm7dlQK26Sp+3TCbjuN8rvr90hdyiIqz09VjXp7fCFDaARxHRfLH/FOl5+dgaGbJtzECczIxLjSsRO4FxyZgZ6PLHxEE4mpcel5GTz5e/HiM5M5fqduYsG98TdQXRy8ycfGasOkZWbgH1q9sw66OOSqMw56++4NSFZ4hEMHdGT8yUWFUD5OUV8uOPJ5FIpLRpW4sOHZU3Iy1BJpOxZvFJcrLzqVXXjr5DFDc6LYs7l17w4Nor1DXU+Hx+v/duVx4fkcyZbfLo0bjvB753m2sBAQGBfyOC4BH4oNA1eC14sqpG8JhbywVPcoLyQv+yEIlEOFWz5MXTCCJCE1USPAC13Wx58SKaV34xdOmq/O42gOdr6+rAkATS0nOU9h0Ri0V0bFqT/ReecOV+gFLBo6GmRv9W9fnj3H0O3vBVKnisjQ0Y0qIBu72f8uu5O7So4ajwMGeiq8MPvTsxef9Jtt55TMfarng4KD5k1zA3Y23fXkw8eoKzAYFoq6uzrHvXMsVLJ2dXzg/5iFnXLnAvNor53lc4HxrE8vZdcTCs2N14fQ0tujnWopujvEajUCLhVVoiPsly8ZOSn0taQR5pBfLvmYV/jtjoqGugr6GJgYYW+hqaWOjoUcvYklomFtQyNqeaoRmaZUStykKR0NEUqzGybkOmNWmpNH0NICUnl/mXLnMhKBiAFo4OrO7VEzMFTWEBTvj6MffkZYokEurZWvH78D5YGpQWE38VO1s/H0w1S9NS4/IKipj6+3HCXttPr5vcDwMFDXCLiyV8t+40UfFyk4Ll0/oojUSGhCfx8/rXVtXDWtHE3Vnp8wdY//sVoqNSMTc3UNmV7dIpHx7cDkJDQ42ZC/q96fulKvl5hWxafBKAQRPa4+D6/m2idyw9QXGRBI92bjRqX76IExAQEPgvIAgegQ8K3ddFzLnZFW8Mqgolgic9OZviIgnqGhU/rDpVs3gteMp3XSuhTh25IHj1Kq7csabGetRwsSQoLJFHvhF0bqf80NOpmVzw3HwSQn5hEdoKajYABrapz7YLD3gUGE1IbDKutoobW47zasKRe895HhXPDb9Q2tdVLKI61nalbwM3Tjx7xbfHLnB84ih0lOzdzsWFNb178uXJ0xx96Ye2ujo/dFZ+lx/AwdCYvX2GsPPFU5bdu8mdmEi6HdzO3JZeDHOrX+m76ppqajQ0t6GhuWKhWiyVklGYj7pYjJ66pko1RBVFJpNxNyaK1Y/+LHSG1anP5x7NsNEv22HsYmAQcy9dJjU3D3WxmC9bNuezZk0VXqtUKmPd9busvylv3NnFrTrL+3dT+F6pKnYKi4qZufEkz0LjMNTVYt3k/liZlL5mmUzGz7uu8fBlJDpaGqyc0Q8zBTbVALm5hcxffoKCwmKaejgzZohiq+oSbt0K5MxpH0Qi+Pa73hgalt98Njkxkw0/nwdg9EQvnCrR0+bA+qskxqZjaWfC0M87VHh+eYQ8j+LaYfl79cm8Ae99fQEBAYF/K0KsW+CDoqojPIYmuqhrqCGTyUhNqlxam9NrE4LICgie2m5ywRMSkkC+Cg50nh7OADz0CS9zXF1XG6zMDMjNL+L+M+UpcFYmBrRrIBcvB2/4Kh1nbqjH8NeObb9euKvUsQ3gu+7tsTTQIyI1nV+uKHdtA+hSswYre3ZHBOz1fcaSazfKdU8Ti0SMrd+Ic4M/orG1LTlFRcy+cZFhJw9wN6Zq3NfUxWLMtHUx0tR+72InoyCfbc+e0PXAdkacOsiDuGg0xWqMqefOjZHjWdimU5liJzM/n6/OnGPSiVOk5uZRy9yco6NGMLlFc4XXml9UzMwjZ9+InQmtm7B6cC+FYic5M4dxKoidYomUOdvOce+VXMSsndyf6naKxfPhyz4cvSpPT1s4qQc1HBW70slkMpb/ep6o2DQszAyYO6NnmXU7SUlZrPzpDACDhzTDw0N5M9+391j9VirboFEty53zV2LCkzi8+ToAn819/0YFANsWHwWgXf8m1CijSbGAgIDAfw1B8Ah8ULyJ8GRVTYRHLBZjZiUvvk6Or1xaW8md4QgVbKZLsLQ0xNRUD6lURkiwYnvot2laIniehpd5sC9JawO4/EB5c1GAIe0aAnDm/iuy8xQ3GAX4xKsJ+tqaBMQmcel5kNJxRjra/NinCwA77z/lQXh0mfv3dqvNkm7y8dseP2H17Ttlji/BxdiEg32HMadFOzTV1LgfG83wkwcZfHw/1yPD/rHNRkF+0H4cH8OMK2dpumMDP9y+SmBaCtrq6ioLHYAbYWF037aT436vEItEfNasCUdHj6COleIoRVJWDh9tP8S5l4FoiMX82LcLMzu1VigkolMyGPPbAYLikjEvQ+zIZDJ+3HuZK0+D0VBXY9VnvWlQTXGk7N7zcH7ZfR2AyUPaKE23BDhw4tGbfjsLv+mDsaHitDyQR6yWLz1FVmY+NWpY88m4dkrHvs2lUz48vB2EhqY6X/3Qv8KpbDKZjA0L5almnm1r0aJT3QrNVwVfb38eXXmJmrqYj2b3fe/rCwgICPybEQSPwAdFSYQnJ7NqBA+AubUxAMlxlRM8jq8jPHHRaRSo2C9IJBJRu7Y8yuPnV3ZTUYD6bnZoaaqTkpZDaETZkaQSweP9JJS8Mq6nSS0HXKxNyS0o4sSdl0rHGelqM6ZtIwB+OeNNXqHyNdvUcGZwI7lL1bfHLpCeW3ZkbnD9eszvKO9Z8tvd+/zsfUslwaImFjPBvQlXh3/C6LruaKqp8Sg+hrFnjtD90E4O+7+gUCIpd52/A5lMRkBKEr89uU/3gzsYeGwfRwP9KJAUU9vUnIVtOnJ/zESVhE50RgaTjp9k3OFjJGRn42xizP7hQ5nVtg1a6oozmu+FRdF/w258Y+Ix0tbij9EDGOih+IAeEJvEmN8OEJWSgZ2pITsnD1Uqdn4+fIMTd14iFolY8kl3mrkpjkCERicz59czSKQyerauw6ienkqf32PfCDbukBfofznOi7q1FNeClbB/312ePo1AW1uDOfP6oKFCSmpifMabVLYxE71wdCm7/5Eibp1/zqObAahrqDFxft/3blQgkUj5Y8ERAHp81BbbSqTbCQgICHzICIJH4INC30h+dzc7XXnTzXfF0tYYgISY1ErNNzHTx9hUD5lMRlhQ+dGaEurUk/esef48qtyxmhrqNG4oP1Deuh9c5ti6rtbYWxqRV1BUZpRHJBIx4nWPlJ2XHlFQVKx07EftGmNlpE9MaibrL94tc/9vurTFwcSI2IxMvjl2HolUWub4MY08+LZdWwDW33vAlFNnyCpQHnF6G3sDIxa17YT3yAmMb9gYXXUN/FOS+OraeZrv3MDMq+c4GxJAVqFq670vCiUSbkVHsODWVdrs2UzXgzv46b43/qnJaKurM6hWXY72H8G5IR8xpp5HmYYEAPlFRay9fZeuW7dzMSgYNZGIjxs34uSY0Upd2KRSGRtu3ueTnUdIzsmlhqUZByYMp5mLg8Lxj0Ki+fj3QyRl5lDd2oydk4fioMCNDeD3k3fYe/UpAPNGdaajRw2F4xJSspj601GycwtoWNOObz/ppFQcRMelMX/FSSRSGV296tK/h+L+PSX4+kSybetNQG5B7eBQttshyBuM/vzD8TepbANHll0bpIis9FzW/3AMgMGfeWHnXHHBVB4X99wmyDcCXQNtRszs9d7XFxAQEPi3IwgegQ8KQ1O5c1RWWk6VpSrZvLaFjotMqdR8kUj0xp0t6FX50ZoSGjZ0BODZs8gya2NKaN2sOgDe5QgekUhEn/Zy57fj156XObZPi7pYmxiQlJHDsdsvlI7T1dJk3kB5d/edN5/gF61c2Olra7FmSC801dS4ERTGj+eul/vejW/qyeIunVAXizkXEEjfnbt5kaC6eLTS02duSy/ujvmMb5q3wUpPn9T8PI4EvGTSxVM02vYbo04dYuuzx4SmpyJ9j58lmUxGfHYWF8OCWfXgFh+fOULj7fL9tj9/QnRWJlpq6nR0qsaSdp25P2YiKzt0p5G1bbmRAZlMxqWgYLpt28HaO3cpKJbQ3NGBU2NHM6dDe4WNRAHScvOYuPc4q6/eQSqT0d+9DgfHD8fZzETh+Csvgvls81Gy8gto5GLLjslDsDRSbAH9x7n7bDn/AIBvhnrRt6XiaFFmTj5TfzpKYmo2zram/DS9D5pKejTl5BYwe/ExsrLzqVPThq8mdSnztUlNzeHHxSeQSmV07lKPrt3Kdjos4cT++/g8CEVLW4OvFw2ocCobwOalp0hLzsbB1ZJhn3es8PzyyErLeVO7M/qbPphYlu53JCAgIPBfR3BpE/igMHoteIoKi8nLLniT4vY+sX5HwQNQw82WR3eCCfYv33WthJo1rdHW1iArM5+wsCRcy7G0bd20OivFFwkMSSA+MQNrS+WWzL3a1GXjkTu8CI4jJCoZVwfFheQa6mp83LUJS/dfZfuFh/RvVU9p49B2darRzb0m530CWXDoMnunDFfYZwWgjo0lKwZ0Y/qhM+x96IuVoT6ftSm7x8mwhg2oZWHO1FNniEzPYPCe/cxu31Zp00xFGGlp87lHM8Y38ORRfAxXIkK4Gh5KaEYat6IjuBUdwcLb19BSU8fF2ARXYxNcjU2pZmyKs5EJ+pqaaKqpoSlWQ1NNDQ01NTTEamQVFpCUm0NyXi7Jr78n5eYQnJbC86QEkvNKRyDNdXTp4FSNTs7VaW3viK5GxYrafePi+OXWHW6Fy80nrA30md2+HT1q1Szz9XgaFcuMQ2eJy8xCS12N+T07Kk1hAzhy/zkLD19BKpPRvm41fhrVE20FnwGZTMamM/fYeOYeANMGtGFoe3eFa+YXFvHVqhOExaRgYaLHmlkDMNJX7JwmkUhZtOoMEdEpmJvqs3h2P6VW1SXjl/54kpSUbJyczJk6ratKn4+I0ES2/noZgE+nd8XeSfHPRFk8vhnApSOPEIlETF86GE2t9/8nd8fSE2Sm5uBU25be49q/9/UFBAQEPgQEwSPwQaGlq4mGljpFBcVkpmVXieApifDER1UupQ3AtZY8whMcoLrgUVdXo359ex4+DMPXJ6JcwWNspEt9Nzt8X0bjfT+Ywb0bKx1rZqxHG49qXH8UzPHrz5k52kvp2L4t67L1wgMS0rI5fvuF0kMswDd923MnIIJXMYnsuvmEj72U12N0q1uTxKwclpy/zi9XbmNpoEd/97KLuz1sbTk5ZhTfnL/IleAQFl65xv2oaJZ164KBVum+LsrQUFOjhZ0jLewcmdvSi9D0VK5GhHIlPITH8bEUSIrxT0nCP0V1Z72yUBOJqGFiRj0LK+pbWNHQ0oYGltYqN0d9G5/YONbducuNsPA3z2WcZ2M+b94UPU3lokkilbLtzmNWX71DsVSKk6kxa4f0opa14pQrqVTG2vO32XL1IQD9m9Zl/sBOCkWsTCbj95N33kR2vuzXijGdFb/3EqmU+b+fxTcwBn1dLVbPGoC1ufIoxZa9t7jzMARNTXV+/K4f5qbKm4sC7Nl9mydPwtHW1mD+gv7oqOCOVlRUzIp5RyksKKZJqxr0HKj8c6uM3Ox81s49DECfj1rh1si5wmuUR/CzSM5ul9cwTVo6DHUlNx8EBAQE/usIvx0FPihEIhGGJvqkxKeTlZqDtWPF78qWh42DvCg7MTa90r14qteyBiAiJLFCazRo6MjDh2E8841iwMAm5Y5v07yGXPDcCypT8AD0bV+f64+COXfLj8lDWyvtyaOpoc7YLk1YfuAa2y/KozzKUo/MDfT4qnc75h+8yG8X7tCpfnWldR4AY5p7kJCZxZY7j5l38jLmenq0qeFc5nUb6+iwoV8ftj9+yoobN7kQGIRfQiIre3Sjsb1dmXOVUe11FGd8Q08kUinRWZmEpqcS8vorND2ViIx08ouLKZRIKJJKKHqr9kgEmOnoYq6ji4WuHua6epjr6OJgaEQ9cyvqmFugra749VWVJzGxrLtzF+/XER01kYi+ddyY3KI5TibGZc4NTU7lu+MX8YmWC+5udWqwuE9n9LUVi8TcgkK+3Xueay9DAJjQsSlfdmupMFIik8lYfdSbXZcfAzBjUDtGdWykcF2ZTMZPO65y43EImhpq/DStD9UdlNe4XL75it2v+8x880VX3GqU3bj38eMwdu64BcC0Gd1wdlbt98GezTcI9o/DwEiH6fMqZzKw85cLJMamY2VvwkfTu1V4fnnIZDI2fHcAqVRGu36eNGxT+73vISAgIPChIAgegQ8OQzO54MlIza6S9U0tDdHUUqewoJjEmDRsVTxEvY2VrTG6elrk5hQQGZ5EtRrWKs1r6C6v4/H1ldfxlNVvBKBNsxr8uuUaz/yiSc/IxdhIuWVvs/pO2JgbEpecycW7AfRpV0/p2H6t6rH1vDzKc6ycKE+/JnU48+QV94OjWHDoMps/G1jmdc/s1IbErBxOPfdn6sHTbBkzAA+Hst23RCIRH3s2orGdLVNOnSYqI4Oh+w7QvVZNprduSTXT0s5hqqImFuNkZIyTkTFeTtWUjpPKZG/Ej666BmpV0HRUKpPhHRbO9sdP/iR0+tetw+fNm5UrdCRSKbvu+/DLlVsUFEvQ19Lk267tGOhRV+mhPiY1gynbThIYl4ymuho/DOlMr0Zuiq9PKuPnw9fZd80HkNfslPXZ2HLsHsde99r54fPuNHJTbJAA8DIglmXr5G5pIwc2K7OhLkBiYiZLFp9EJoMePRvSubPyz/Of9vGJ5MA2bwCmzumDmUXZTniK8PeJ5OROeW+pLxcNREdP9Wijqtw69YQX94LQ0tFg/A+D3vv6AgICAh8SgmmBwAeHkZk8xSU9uXKNQctDJBK9ETnRYZVLcRKLxW+MCwJexKg8r1YtG3R1NcnMzCMwsPx0OBsrI2q5WiGVyrji7V/mWDWxmIGd5L129p57XKYxgpaGOp90k9fYbDpzr8y+PCKRiO8HdUJHQ50HIVFsvfawzOsQi0X82LcLLas5kltUxPhdx3gapZq5QwMba06OGcXg+vUQAecCAum+dQdzLlwiLitLpTUqi1gkQltdHQNNrfcudlJz89h0/yEdN29l3JFjeIdHoCYSMah+XS6O+5hl3buWK3YiUtIZs/0Qyy7coKBYQstqjpz8fDSDGtVTKnYehUQzfM2+PzUUVSZ2JFIpi/dcfiN2vhvRsUyxs//CEzYfkzv4zRzdgQ5NaiodGx2XxreLj1JYWEzLJq6MH9m6zOdaWFjMgu+Pkp6eS/XqVnzxZecyx5eQnZXH8rlHkEpldOzZkDYdyxZVCvcuKGLVNweQyWR07NeIxm1qVXiN8sjPLWDTvIMADJrcFQu7ygt6AQEBgf8CguAR+OAwtZIX56dVsjGoKjhWtwIgUoUmoMpwayC/m+33rHyb6RLU1dVo7OkCwL27ZbuvldCtg/zO9vmryl3VSujv1QA9HU3CYlK45RNa5tgBberjZGlCWnbem8J0ZTiYGzO7fwcAfr1wB5/wsgWMproavw7rQzNnB3IKCxm/6xjeQeHlXj+AobY2S7t14fTY0XRwrYZEJuPAs+d0+mMry6/fJDW36no0vU9kMhlPYmKZeeYcrTZsYsVNb6IyMjDU0mJs40ZcGv8xy7qVL3SKJBK2331C3/W7eBwZi66mBj/06siW0QOwNVZeK3Po3jMmbDxCWk4edewt2T91BA2dFKeQFRVLmLftPMfvvEAsErHwo64MatNA6dpHLvu+aSw6oX8LBnd2Vzo2PTOXrxceISMzj5quVsyf2Qs1JeYXIH/d1qy+QIB/HAaG2ixYOAAtrfLTB2UyGasXnyIhLh0bOxMmf92j3DmK2LP2ElEhiZhYGPDZ3KppAHpgzXmSYtKwtDdl8JSuVbKHgICAwIeEIHgEPjhKBE9qQtULnoig+EqvUee14HlVAcED0LyF3G76/r0QlcZ3bFsbdXUxASEJhISXHZHS19ViYEd5lGfHqQdl2kNrqKkxa2h7APZfe0pgdNlr92tSh+4etZBIZczcdYakzLJTDnU1NVg/oi/NXeSi57O9x9l657HKduO1LCzYNKAfB4YPxdPOjoJiCZsfPqLVhk1MPnGKy8EhFP1Dmo2WIJFKeRAVzeKr1/HavIUhe/dzwu8VRRIJDaytWNatC7c//5S5HdrjaGxc7nq3giPot343yy7cIL+4mBYuDpyaNIahng2URnVyC4qYf/AiCw9foVgqpbt7LbZPGoK1seLUruy8Aqb8dpzzjwJQF4tZOq4HvZorj4ycuP6cFTuuADC6pyfj+jdXOragoIjvfjxGdGwaVhaGLJs7AN1yTAdOn3rK+XPPEItFzJ3XDxsb4zLHl3DhxBO8L79ETU3M7KWD0dOvuOFJwLMoDm++DsCXCwdgYKw8hbSyxIYlcvjXCwB8ungI2rrvP11OQEBA4ENDqOER+OD4OwSPU42SCE9ipddwq28PQFR4MpkZuRiWUV/zNk2buiISQWBgPMnJWZibl11jYGyoSwtPV7zvBXH+2gsmf6zcgQ1gWNdG7L/whBfBcTz1jy6zrqJlHWc6NarB5SdBLNl3ha0zhyqtzxGJRMwf2JGAmCRCE1OZsu0k2yYNUWhpXIKupgabRvZn4ZmrHH76ghUXbxKQkMTCXp2U2mH/lcb2duwbPoQbYWGsvnWXFwkJXAgM4kJgECY6OvRxq03/unWoa2VZqeL0dyWvqIh7kVFcDArmSkjInyJQ2urq9HKrxUj3htS3Vq3OCyAyNZ1lF25wNUAepTPR1WFGx1Zlpq8BBMUlM2v3GUISUhGJ4IuuLZnQsanSOUnp2Xzx6zGCYpLR0dJgxYRetKrrrHT9M94vWbr1EgDDuzVi8tA2SteWSmUsWXOOF/6x6Otp8dP8geU6sr18Ec2v6+TrfzK+HZ6vo6HlERmWxO8/nQNg7OSO1KpbcbOLwoJiVn0tNxFo38eDFirWDFWUjXMPUlRQTKP2brTqWXazVQEBAQEBOYLgEfjgMLM2Bv6eCE9kcAIymaxSB2UjEz3sHM2IiUwh4EUMTVop7j7/V0xN9ahVywZ//zju3w+hZ0/3cud071AP73tBXLrux2dj2inthwNyi+pebepy9Oozdp5+WKbgAfhqcHvuvAznWWgcJ+68oH9r5U0d9bW1+PWTvoxYu48XUQnM3X+Bn0b1KPP101RXY1GfTtSyNmfZ+Ruc8H1FeHIa64b1xtKg7ANwCSKRiPbVqtG+WjVeJSZx7KUfJ/1ekZyby44nT9nx5ClOxsY0sbfDw84WD1sbqpuZVcomuixkMhmR6Rk8jY3FJy6Op7Fx+CcmIXkramWkrUUHV1e61KhOa2cndDRUd3PLKShkg/cDtt99QpFEgrpYzMimDZncrjmGOsojFjKZjCP3X7Ds+DUKiiVYGOqxbER3mlZX/t6HxqXwxa/HiE/NwsxQlzWT+lHHyUrp+At3XrFo8wVkMhjc2Z2pI9qV+b5v2HGDa7cDUFcXs/jbfjiX47iYkpLNgu+PUlwspW272gwbpjxy9DaFBUUs/e4wBflFeDSrxqDRLVWa91f2/XaZyOAEjM30+Xxe1aSyPbj0nPsXnqGmLubzpcP+XwS6gICAwL8RQfAIfHD8HREeWydz1DXUyM8tlFvP2inuSF8ebvXtiYlMwc83UmXBA/K0Nn//OO7dDVZJ8DRv7IKxkS6p6bk8fBpGC0/XMseP7OHJ8WvPufssnIDwRGo5K+/5Y2msz8TeLVl1+AZrj9+ifUNXTAyUR6sczI355aPeTNh0hAu+gThbmPBFt7IPmSKRiNHNPHA1N2X6oTP4xsQzaNNe1gzpVa6D219xs7TAzbIdX7drw63wcI69fMWloGAi0tOJSE/n8IuXABhqadHQxpr61tZYG+hjoaeHpb4elvr6mOvqoqGm2EpcIpWSmJNDTEYm0RkZxGZmEZ2ZQUxGJq+SkhTWENkYGNCxejW61KhBE3s7pWsrI7+omIOPn7H51kOSsuVNTVu7OjG7WztcLczKnJudX8DCw1c45xMAQKtaTvw4rBtmZbyHT4Kimb7+JFl5BThZmvDrl/2xM1fe2Pby/QAWbDiPTAb9OzRg5mivMg/rR848Yf9xubnFt192o1EDxzKfQ1GRhB++P0pqag7OzuZ8/U1PlcXAlnWXCQ2Mx8hYl1k/DEBcCcOJoBfRHNx4DYAvFg7A0ESvwmuUR2FBERu+OwBAv8864VCOJbeAgICAwP8QBI/AB0dJhCc5Lq3S0ZfyUNdQw97FgvDAeML84yoteOq6O3L5jC/Pn0ZUaF6LljXYvs2bx4/CyM0tQLecPH51dTW6tHPj4MnHHD/nU67gsbcyplPzmly8G8CGw7f55av+ZY4f1t6dU3dfEhSTzKI9l/n5s95lvu6ervbMH9iR+QcvsfHyfYz1tBnVRnGvlrdp6erEgQnDmbzvJCHJqYzedohxrTz5rE1TdJX0DVKGulj8JuqTVVDAo+gYnsTG8jQ2Dt+4ODILCvAOj3hj//w2IsD4dcSkWCqjWCqhWCpDIpUiLafGSENNjXpWlrjb2OBhZ4u7jQ02BvqV+pwWFBVz4PHz10InBwBHEyO+7dYOr5rVyl3zeWQ83+w5S1RKBmpiEVO6t2JsO88ybcMvPAxg/s4LFBVLaFjNhl8+74uxvo7S8ZfuBfD9+rNIZTJ6t63L1x91LPO6rt0OYO1meY3PuJGt6dK+7OazJSYFL1/GoKenxQ+LBqrUXBTA+4ofx/fJDTdmLuhfKQvqgvwifpq5D6lEStseDWnVVXmE81048Ms5YsMSMbUyYsRXPatkDwEBAYEPFcG0QOCDw/y1+CjIKyIjpWp68QC4vs7zD34RXek13JvI+7q8ehZNXq5ya+dSe7taYu9gSkFBMbdvB6k0p18PD0QiuPsolKiY1HLHTxjQEjU1MXd8w3j0MrLMsepqYhZ+1BV1NTHXfUM4flsFR7im9ZjUpQUAy0/c4PjDlyo9D2czEw6MH0aPujUplkrZ6P2Anr/u4KJfkMqGBn/FQEsLL9dqzGzTmt1DB/N0yhccHzOSBZ06MKxBfTq4VqO+tRXWBvqoi8XIgLS8fNLy8skqKCCvqJgiieSN2FEXi3EwMqK5owMD69VlSssWLO/elcMjh+MzZTKHRg5nTof29KhVE1tDgwqLnYKiYnbf96Hz2q0sOX+dpOwcbI0M+KFXR05P/ogOtVzLXDO/qJhVp28yat1+olIysDUxZPukIXzi1USp2JFKZaw/dYfZW89SVCzBy70666cOKlPsnLz+nPm/n0UildGzTV1mj+tcppi69ziURatOI5NBn64NGTO4/LS0QwcfcO6sr9ykYH5f7O1Vs2iOiUxh1Q/HARg8phXN2ii3xS6LbT+dJSokEVNLQyb/UPaNgcoS7h/LgTXyGqPPlw5Dz0D5ay4gICDwNr///jsuLi5oa2vTuHFjvL29yxx/48YNGjdujLa2NtWqVWPDhg1/+vejR4/i6emJsbExenp6uLu7s2vXrlLrxMTEMGrUKMzMzNDV1cXd3Z3Hjx+/1+dWEYQIj8AHh6aWBmbWxqTEp5MYlYJxOUX9laVGPXuuHHtM0DsIHht7E6xsjUmITefFU9XT2kQiER071mHH9ltcvfJSpaaK9jYmtPB05c7DEI6cecK0TzuVOd7R2oQBHRpw6JIP6w54s23BiDIPq7UcLJncpxVrjnnz06HrNK5pj6Nl2ZGviZ2bkZVfwK6bT/j+4CX0tDTp3KD810BfW4ufB/WgZ/3a/HjuOrEZmUw5eJpWrk7M7e6Fi3nlIm4lqIvF1LOyop5V6ZoUqUxGWl4eKbm5iBChoSZGTSRGTSxGQyz/bqithXoVNB5Nzs7h8JMX7Hv4jIQsuZi3MTTgs7ZNGeBeF0318lPhnobFMP/gJcKT0gDo7lGLOf07YKSrvMYnK6+AudvO4f08DICRHRsxbUCbMvsN7Tn7iLX7bgLQz6s+X4/tWOZ4n5dRzF12guJiKR3b1Gb6Z53KFYK3bwWyaeNVACZ+3pGmTcuOXJZQkF/Eoq8PkJtTQF13R8ZO6qjSvL/y9HYgJ3bcAmD60sFVksomlUpZO3MXxUUSmnVtQOve5UdCBQQEBAAOHDjAtGnT+P3332nVqhUbN26ke/fu+Pn54ehYOlU4LCyMHj16MGHCBHbv3s3t27eZNGkSFhYWDBw4EABTU1PmzJlD7dq10dTU5PTp03z88cdYWlrStavcJj8tLY1WrVrh5eXFuXPnsLS0JCQkBGMV3EWrCkHwCHyQWDqYkhKfTkJUCjU9nKtkj+r1Xkd4XqreOPSviEQiGjVz5dyxxzy5H1KhOh6vDnLB8+hhGOnpuRirYIE7uHdj7jwM4dyVF4wb0RqDcqx3x/VrzhlvP/zDErh0P4CuLWqXOX50p8bcfhnOo8Ao5m47z5avhpRZjyISiZjVuy3Z+QUce/CSr3ef5YchnenjWX7DR5FIRMfarrSs5sjmWw/54/YjbodE0Of3nYxt2ZjP2jRFX0u11KaKIBaJMNPVxUz3/VsOK0Imk/E4Moa9D59xyS+IIqkUAGtDfT5r05SBHnXRVC//V3luQRHrzt9mz62nyGRgYajHvIEd8apbtkgIjUth5oZTRCSmoaWhxpyRnejVTPn7I5PJ2HjkDttO3Afk1tNlubEB+AfF8+2i/zUWnTOtR5m9dgCCguJZ8uNJeTSojwcDBnqWOf5tfltxhrCgBIxM9Phu6WDUNSpWMwWQnZnHqm/kzT97jmiBZ7uyfzYqy6V9d/C7H4K2nhZfrBghGBUICPxDyMsvQkOz6G/dr6KsWrWKcePGMX78eABWr17NhQsXWL9+PUuXLi01fsOGDTg6OrJ69WoA3NzcePToEStXrnwjeNq3b/+nOVOnTmXHjh3cunXrjeBZvnw5Dg4ObNu27c04Z2fnCl//+0QQPAIfJFYO5rx6GEpiVEqV7eHqZodYLCI1MZPUxExMLZU3cSwLj6bVOHfsMU/vl93o8684OJhRs6Y1gYHx3LzhT5++5d/5bdTAERcnc8Iikjlz+TnD+jUpc7yJoS4f9W7C+kO3WX/wFu0bV0dLU/mvDbFY3nRyyOJdvAiPZ8Opu3zZr3WZe4hEIr4f1InCYglnnvgzZ/8FkjJz+MTLU6XDnY6mBlM6tKRvwzosOX+dG0FhbL71kP0PnzG4cT1GNnXHrowGm/9U0nPzOfsigH2PfAlK/N/nuKG9DSOaNKBbnZoqW3PfC4rkh8OXiU6RG3n0a1KXWX3aluncBnDNJ5j5Oy6Qk1+ItYkBKz/rXaYTm1QqY9Xuaxy65APApCGt+ah30zL3CI9MZtYPh8nNK8SjviM/zOqNejmRqqSkLOZ+d5j8/CIaezoz+cvOKguB88cfc+HEU8RiEbOXDMK8kj+36384TnJ8BrZO5oz/tlel1iiPzNRstvxwBIDRX/fGwk61dD0BAYGqp+eXG1HTrHi/rsoiKcwHIDMz80+Pa2lpoaVVuo63sLCQx48f8+233/7p8S5dunDnzh2Fe9y9e5cuXbr86bGuXbuyZcsWioqK0PiLa6hMJuPq1asEBASwfPnyN4+fPHmSrl27MnjwYG7cuIGdnR2TJk1iwoQJqj/h94xQwyPwQWLpID8YJFSh4NHW1cS+mty97F2iPO5NXBCJRIQFJ5CanFWhuV4d5Xfar1xRrf5FJBIxuFdjAI6cfkJxcfmNN4d1bYSFiT5xyZnsPVd+/q21qQFzR8pThLZdeMhVn+By56iJxSwZ1o2P2smvbfXZWyw7cR3J62iGKjiZGbNhRF9+H9YHZzMTsgoK2HrnMZ3XbGXqwdM8DI+udI3P30VqTi4HHj3jk51HaPXTBhaevUpQYgo6GuoMblSPo5+N5MD4YfRtWEclsROdksH0HaeYsPEI0SkZWBsbsGFCfxYN7VKm2Cmp15m58RQ5+YV41rRnz+wRZYqd4mIJCzed59AlH0Qi+PqjjuWKndj4dKbPP0hGVh5uNWxY+l1/tLTKNp/Iyytk3pzDJCdn4ehkxvzv+5crkEoIehXLr8vPAvDR5x3waFpNpXl/xfvcM66eeIJYLOKrlcPQ1n3/kUSAbYuOkZmag7ObLX0/7VAlewgICPy7cHBwwMjI6M2XokgNQHJyMhKJBKu/pGZbWVkRH6+4aXp8fLzC8cXFxSQnJ795LCMjA319fTQ1NenZsyfr1q2jc+fOb/49NDSU9evXU6NGDS5cuMDEiROZMmUKO3furOzTfmeECI/AB4mVg9yKNz4iuZyR70aNenZEBicQ4BtJUy+3Sq1hZKKHay1rgv3jeHw3hM693VWe6+XlxqYNV3nxPJrY2DRsbcuvXencvg6bd3uTkJTJpRuv6N6x7PofbS0NvhzWhvnrz7HtxD06Nq2Jo03Z+3RpXItnoXHsvfqUudvOsXn6YOo6l904UywW8VXvtlga6fPTyRvsveVDRFI6K0Z1LzcSUYJIJKJDbVfa16zGzeAwdt57yp3QSC74BXHBL4ialub0d69DuxouuJib/CPSgxIys7keGMr5l4E8CI/+U0+e2lYWDGxUl34N62CgXbYT39vkFhSx5dpDtl9/RGGxBDWxiCEtGjKle0v0y1knKSObedvO8yAgCoDhXh5MG9imzNTEvPwi5v52hls+oaiJRXz/WTe6tiz75yEhKZNp8w6QkpaDi5M5P30/EN1yhINEIuXHxScICorHyEiHH5cMRr+ctMwS0tNyWPjVfooKi2nethZDxpYdeVRGYmwaa+ceBmDIxA64eThVap3yeHY7gHO75MXFX/w0EnUVo3kCAgJ/D2fWfYah4d+XPZCZmYn1wTlERUX9aV9F0Z23+evfufLcaxWN/+vjBgYG+Pj4kJ2dzZUrV5gxYwbVqlV7k+4mlUrx9PRkyZIlAHh4ePDy5UvWr1/PmDFjyn+yVYDwG1Tgg8SumvwORUxoYpXu49bImSvHn/Dycfg7rdOsTU2C/eO4c/1VhQSPhYUhjRu78OhRGOfOPmPc+HblztHSVGdY/yas336D7Qfu0LmdW7l3yLu0qM1pbz8evIhg0R8X2DBnSJkF6ABTB7QhLD6Vu34RTPntONtmDcPR0rjc6xvTthFWRvrM3X+B2wHhjFy7n7Uf98HFUvV0HrFYRPua1WhfsxoBCcnsvv+U08/9CUxMZvnFmyy/eBN7Y0Pa1nChbQ1nmjk7oFNBW+vKIJPJiE7L4GFEDA8jonkUEUNU2p/7RdW1saRb3Zp0cauBk5lxhdc/7xPIz6dvkpAhNzVoVt2Br/u2p6ZN2Y07AW69CGP+jgukZ+ehranOdyM6llmvA5CUls3Mn48TEJGIloYaS77sTWuPsiMncQkZTJt3gPjETOxsjPl5wWAMy3Eek8lk/PbrJe7eCUZTU51FiwepJPABiosk/PjNQRLjM7BzNGPWwv6V6rcjKZawfPpesjPyqNnAgRFflG38UVnycwr4ZeoOALqPaUO95qrX9gkICPw96GhroKNd9X83SigqlO9laGioktAyNzdHTU2tVDQnMTGxVBSnBGtra4Xj1dXVMTP7X083sVhM9erVAXB3d+fVq1csXbr0jeCxsbGhTp0//+1wc3PjyJEj5V53VSEIHoEPErvq8h/m+IgkiouKq+zuaD1PFwD8fSIoLpJUqvgZoJWXG3s23+Dx3RDy8wrRVrGPCEDPXu48ehTGhfPP+Ghsa5XSe/r38ODA8YfEJWRw7uoLendpWOZ4kUjEd+M6M2L2Dp4FxnLokg/DupZdM6ShpsaKCb2YsOoQ/lGJfPnrMbbPGlpmU9ISujasiYOZEVO3nyI8KY2Ra/fzdd929PWsU+GoTC0rcxb16cyszm04+cyfqwEhPIyIITo9k70Pfdn70BdNNTXcHWyobmFGdQszqlmYUt3CFDM93UpHgdJy8ghLSSM8JU3+PTmNZzHxb9zVShCLRNS1saRLnRp0q1MDB1PjCu8lk8l4GBLNr+fv8DQ8FgA7E0O+6tOWjvWql/scCouKWXv8FnuvPgWgpr0FS8f1wMW6bJEZGJHIjJ+Pk5SWjYmBDj9N70v9GmU3go2NT2fq3AMkJGViZ23M6kVDMTfVL/c57t1zlxPHnyASwezvelO3nn25c0rY+Mt5nj0OR1dPiwWrhqNfSVvnPb9exu9xODp6Wny7eiQaZdSzvQvblxwnLjwZCzsTxv8wqEr2EBAQ+LDR1NSkcePGXLp0if79/2eZf+nSJfr27atwTosWLTh16tSfHrt48SKenp6l6nfeRiaTUVDwv9YarVq1IiAg4E9jAgMDcXKqmoi4KgiCR+CDxNzGGC1dTQpyC4mPSMG+uvLag3fBobol+kY6ZGfkEeIXQ62GZXeEV0a1mtZY2RiTEJfOk3shtKxAelyLljUwNtElJSWbe/dCaN26/H4i2loajBzUnHV/XGXnwXt09aqLZjmi0MbckC+Ht2P5tsv8fvAWrdxdcLAq+w67nrYmayf3Y+xP+4lKSmfq7yfYOG0QOuXUaQDUsbdi39ThzNhxmqfhscw7cJHzPgF8P6gTNiYVTyMw1NFmVDN3RjVzJ6egkPvhUdwMCudmUBixGVk8CI/mQfifLcaNtLVwMjPBQFsLXU0N9DQ15d+1NNHRUCevqJicgkJyCgrJfv2VVVBATHomGXn5Cq9DQyymvp01nk52NHGyx8PBptw0M2XIZDLuB0ex/uI9noTJ68h0NNQZ17EpH7VrjLYKQj88PpXZW84SEJ0EyFPYpvRvXW6N0C2fUOb+eoa8giKcbU1ZNbMfduVE8KJi05g29wBJKVk42JqwevFQLMzKt40/c8aHrVtuADBpcifaVsAR7cKJJ5w88ACArxcNwNHFQuW5b+N7N5j9v8kbok75cRA2jmblzKgcL+4FcWKT3Gp76i9jhJ47AgIClWbGjBmMHj0aT09PWrRowaZNm4iMjGTixIkAzJ49m5iYmDe1NRMnTuTXX39lxowZTJgwgbt377Jlyxb27dv3Zs2lS5fi6emJq6srhYWFnD17lp07d7J+/fo3Y6ZPn07Lli1ZsmQJQ4YM4cGDB2zatIlNmzb9vS/AWwiCR+CDRCQSYe9qRcjzKGJCEqpM8IjFYuo2duH+VT9ePAyrtOARiUS09KrNsb33uHPdv0KCR0NDja5dG3Bg/z3OnvZRSfCAvLHjvqMPSEjK5Myl5/Tv4VHunP5e9blyP4BHflEs3nyR9d8NKbM3D4C5kR6/ftGfj1ce4EV4PN9uOcPPn/VBvRzbYQBzAz22fj6YnTcf89uFu9wOiKDfyp3M6NmGwc0blLu3MvS0NOlQy5UOtVyRyWSEJKXyLCae0ORUgpNSCE1KJSotg4z8Ap7FKC7uVAUbQwOczYxxMTfF2cyYmlYWNLSzfuf0OZlMxt2gSDZcvPcmoqOprsbAZvUZ16EJVkblR0ykUhlHbz9n1eEb5BcWY6ynzYKPutK2fvmF/AcuPGH1nhtIZTKa1HVk6Ze9MNAru5YmIjqFaXPlNTtO9masXjwEM5Pyr/OWdwCrV50HYMTIlgwYWLaz4Nu8eh7FuqWnARgz0YsWlbSOTk/J5qev9iGTyeg6uCnte7lXap3yyM8t4JcpO5DJZHQZ2QrPDnWrZB8BAYH/BkOHDiUlJYWFCxcSFxdHvXr1OHv27JtIS1xcHJGR/2ss7uLiwtmzZ5k+fTq//fYbtra2rF279o0lNUBOTg6TJk0iOjoaHR0dateuze7duxk6dOibMU2aNOHYsWPMnj2bhQsX4uLiwurVqxk5cuTf9+T/gkj2T7cteo9kZmZiZGRERkbG31poJvD/w5Jxm7h54hETFg5m4KTO5U+oJIc2XWPrirO06FyX+evHVnqdZ4/DmfXpNgyMdDhwcRZqKjpPAURHp/LR6I2IxSJ27/0cKysjleYdO/uUXzZextxUn30bJ5RpOV1CbFIGI2bvJK+giJmjvRjSpXyhBOAbEsvENYcpKJLQu0Ud5o/qXG4d0NuEJaby/cFLbw74ntXs+WFIZxzNjVVeoyLkFxUTnpJGdFoGOYWF5BQUkVNYSG5hETkFheQVFaGjoYG+liZ6r7/0tTTR09TExsgAJ1Pj914XVCSRcOV5MLu9n+IbEQfIhc7g5vX5xKsJlioIHYDIxHQW77nEo0B5RMuzpgM/ftwNC+Oy5xdLpKzec/2N7XTf9vX4+qOO5aZRhkcmM23eAVLTc6nmZM4vC4dgYlx+k05fn0i++Xo/RUUSevRsyIyZ3VVOMUyMz2DKmE2kpWTTqoMbc5cPqVTdjkwmY8Gn23hw7RUOrpasPTa1ylzZNs07xNH1lzCzNmbj7QXoG/09vZ4EBP5p/JPPa/9f1/ZPfk3+DQgRHoEPlpI6nuigyt+hV4W6r+t4Xj4KQyqVVupQBVC3oQNGxrpkpOfi+zicRs1U6xoPYG9viruHEz5PIzhz2odPxpVvXgDQs3N99hy5T2JyFkdPP2H4gLJthAFsLYz4clhbVuy4wq8HvPGs60g1u/LTexq62rLkkx7M2nSaU3f9yM0vZNHY7mirWAfhYmnK9klD2HfHhzVnbvEoNJr+K3cypEUDxrb3VCmqURG0NdSpbW1BbevKpUC9T5Kzcjh87zmH7j4jMTMHAC11NQa3aMAnXp5YGKr23CVSKXuuPGH9qTsUFEnQ1lRnUp9WDPdyL1d8pmTkMPfXMzzxl4ukL4a1YVSP8nslBYclyq2nM/Oo4WLJzwsHY2xY/kE+MDCeeXMPU1QkoWWrGkyb3k1lsZOXW8CCGXtJS8nGpboVs36onEkBwJEtN3hw7RUamurMXjOyysTOq0ehHNtwGYApq0YJYkdAQEDgPSL04RH4YHGqZQNAuH/le+SoQo169mjrapKZlkuYf1yl11FTV6NVB3kq2/ULzys8v18/eQ+bkyeekJdXqNIcTQ11xo2Q2/NuP3CH5NTscmbI6d+hAc3qO1FQWMycdafJL1CtA7SXe3WWjuuBhroaV54GM2ntETJyFNe6KEIsFjGytQdHvxpDi5qOFBZL2O39lO5LtrLoyBViUjPKX+RfxPPIeGbvPUeXxVv47cJdEjNzMDPQ5bNOzTj/3Ti+6dteZbETHJPM2BX7WX3Um4IiCU1rOXBw7mhGdWxUrth5HhzLR/P28MQ/Gl1tDZZP7c3onk3KFSA+L6KYMmc/GZl51HK14pdFQ1QSO1GRKcz+5gA5OQU0aODA3Hl9UVMhBRLk1tVLvztMSEA8RiZ6LPhlODq6lauRev4glG0/nQPg0zm9caldtiFDZSnML3qTytZxSHOadWlQJfsICAgI/FcRBI/AB4tLXbmLU7hfDNIKNLCsKBqa6m/c2p7dD32ntby6yQ86t668olBFEVFCy1Y1sLM3ISsrn7NnfFSe19WrLnVq2pCXX8TGnTdVmiN+3WvFzEiP0JgUFm2+qHJTz86Na/Lbl/3R19HCJySWj1ceIDalYkLF3syIjRMGsPHTATRysaNIIuHg3Wf0XLaNufsvEJ6UVqH1/kmEJaay/uI9+v20gxFr93H6iT9FEgkNnGxYOqIbl+aM54tuLTE3LD8lDCCvoIj1p+4wYukeXkYkoK+jxfxRnVk/dSD2FsZlzpXJZBy94svExQdJSsvG2daUrQtG0N6zfJvk63cC+GrBIbJzCmhQx45fFg0t13oaICE+g69n7Sc9PZeaNa1ZvGRwuc1I32bTqvPc9w5EU0udH34ZjrWK1tV/JTUpk6VTdyOVSPHq40HPES0qtY4q7P35NJGBcZhYGjLxx6HlTxAQEBAQqBCC4BH4YLF3tUJDU528nAISIlOqdK8GzeXpZ8/uBb/TOvU8HDG3MiQnO5+Htyu2lpqamKFDmwNw+NBDioslKs0Ti0VM/bQjABeuveSFihExMyM9fvyyJ+pqYi7fD2DrifsqX6tnTQe2zhyClYk+4fGpjF2xn1eRCSrPh9dGDzWd2DF5CNs+H0zLmk5IpDJOPPKj74odTNx8lOMPX5KpxC3tn0RUSjp/XH3AoFW76bNiB79fvEtIQioaamr0aezG/qnD2fPlMHo1ckNDxdouqVTG6ft+9F+wnc1n71MskdKuQTWOzB9Dv1b1yo3O5BcWsWjzRZZvv0KxRIpXkxpsXTACFxXSF4+dfcr3K05SWCShTfMa/LxgMPp65UdZEhMzmTljL4mJmTg6mrFsxVD0VJhXwon99zi+X/45/HrhANzqO6g8920kxRKWTd1DWlIWTjWsmLJ4UJU1qQ3yjeDg2guAvMGogYlqQlZAQEBAQHWEGh6BDxY1dTUca9kQ8jyKML9obJyrrhajQXN5A67nD0KRSKQqp9/8FbFYTPsu9Ti86w7XLjx/k+KmKp271GPb1pskJmZy7aofnbvUV2meWw0benSqz9nLz1m96Qobfxql0nPwqGXPN2M78uOWS2w6cgcXO1M6NFHNJa66nTk7vh7OF78eIzgmmfGrDrFiQi9a1XVWaf7beLra4+lqz/PIeDZdvs91v1BuB0RwOyCChYfVaFXLia7uNfGq44qedtXUYFSEjNx8HoVG8zA4ivvBUQTH/0+Qq4vFNK/pSLeGNelQrzoGOhVPx/IJiWHloRv4RchFpK2ZIdMHtKWDR/k9eQBiEtOZve40AeGJiEUiJg1pzaie5dfryGQy/thzi12H7gFyJ8Dpn3VS6bOUlJTFzOl7iItLx9bWmBUrh2NUgTqWezcD2PCz3M3tky870aZT5R3Odqy6wPMHoejoaTH3tzFVVrdTXFTML1N3IJVIadvXk1Y9VTMAERAQEBCoGILgEfigcalj/1rwxNBSBdvlylK9ji26+trkZOUT+iqWGhVoivhXvLo14PCuO9z3DiAnOx89/bLtft9GU1OdgYOa8Mfm6xzYf59Oncu/k1/Cp6PbcPNuIIEhCRw9+5TBvRurNK9P+/qERKew/8ITFmw4j62FEbWdVbMBtzTWZ8vMIXy18RQPA6KY8tsxxnVrxqc9m6tkW/1X6jtas+6TvkQkpXHeN5DzPgEEx6dw3S+U636haKmr4enqQEMnGxo62VDf0bpSgqIiSKUyolMzCIpPxicslgchUbyKSeTtDECxSETT6g50c69Jx3rVMdarXO+V2JQM1hy7xaXHgYC8D9K4bk0Z3sGj3L46IBcsZ7z9+HnXVXLzizA20GHx5J40qVu+3XqxRMrK3y9y9rK8/mzciFaMGdJCpc9fSko2X83cS2xsOjY2xvz8y0gsLMrvz1NCsH8cS787jFQqo1vfRgz5qLXKc//KvcsvObTpGgDTlw7Gvpplpdcqj4NrLxD6IhpDUz0mLRtWZfsICAgI/NcRBI/AB41LHTsAwl5GlzPy3VBTV6NeExceXHuF793gdxI8rrWssXcyJzoimdtXX9GlT8WEWu8+Huzdc4ewsCTu3g2mZcvy6y0ATI31mPhRO1b+fpE/dnvTqokrttbGKs39cnhbIuJSufssnK9WnWDz/GHYmKtmm2mgo8WvX/Rn6b6rHL/zgj/O3efeqwh++KgrLtamKq3xV5wsTPisUzM+69SM4PhkzvsEcsE3kPCkNG4HhHM7IBwAkQhcLEyp72iNm50l1sYGWBnpY2Wsj6m+rsq22RKplLScPFKz80jOyiEsIZXAuGSC4pIJjk8mr6i41BwXS1OaVnegqas9Tao7YFJJkQOQmJ7N1vMPOHb7BUXFEkQi6NeqHpN6t8RMxVqfzJx8lm29zJUHcrHkXsuOHyZ2x1qF9zE3t5Affj7F3UehiMUiZn7emd5dGqq0b2qqXOxER6ViZWXEz6tGYGmpuuVqQlw686ftIT+vEPem1fhydq9Kp5/FRiSzctZ+APqObU2bHqo9h8oQ+jKavSvlPYI+XzIMYwvBZlZAQECgqhD68Ah80Dy9+YrZA37BytGMHU+WVulex7d7s3HxSRo2d2XZ7onvtNbeLTfY8ftV6jZ0ZNXWcRWev2njNQ7sv0f1Glas3/Cxyg06pVIZU+fux/dlNHVr2bJu6XCVIy3ZuQWMX7ifsJgUHK1N2DRvKCYqOHK9zYWHAfy49zLZ+YVoaajxRd/WDPfyqHSD0beRyWQExiXzODSGZ5Fx+EbEEV2GWYK6WIy5oR5m+rqoqYkRi+SRGJFIhFgkQiaD9Jw8UrNzScvNo6zfpFrqalSzMsPNzpKm1R1o4mqvcs+cskjKyGb7hYcc8X5O4euarSa1HJgxsC21HFSPTDx5FcX3G86RmJqNmpqYTwe0YHSvJioJvriEDL798ShhEcloaqrz/Ve9aNNMNZGdmprNzBl7iYxIwcLCgFWrR2JbAZOBjLQcZozbSnREMk6ulqza8gn6KhgjKCI/t5Dpg9cRHhCPm4cTy/dMRENFy/SKUphfxJTOPxL+Kpbm3Rry/a5JVVYjJCDwb+SffF4T+vD8OxEEj8AHTXZGLoNcpwGw3/9njM1VT5OpKLERyYzruBw1dTEHHi5Ar5IHL4CUpCxG91yFRCJlw/5JuNRQLUWshIyMXEaNWE9ubiHzF/SnXQU6zMcnZvDx1O3k5BbyyfBWjB3WUuW5CalZfLpwP/EpWdR2seK32YPQr2DKWHxqFgt3X+TeK3n358Y17Fkwpgt25qo1U60Iqdm5PI+MxzcijvDEVBIysonPyCY5MwdpBX81ikRgoquDqb4uDubG1LQxp4aNOTVtzHE0N65Qk9XySMnMYfvFRxy+6UtBkVzoeFS3Y2KvFjSppXqhfnGxhE1H77Lz9ANkMnCwNmbh5z2oU81apfnP/KKZu+wE6Rm5mJroseS7/tSpaaPS3FJi55eR2NqpLnby8wr5ZuIO/F9EY2FlxC/bxmGhYsPdvyKTyVg2bQ83z/hiYmHAuuNTMavkWqqwcc4Bjm28grGFARtufi9EdwQE/sI/+bwmCJ5/J0JKm8AHjb6RLnauVsSEJBDsG4Fnx3pVtpetkzkOrpZEhSTyxDvwndJhzCwMaNG+Nreu+HHm6CO++KZnheYbGekycFATdu28zdYtN2jVqgbqKrp7WVsaMWNiZxatOsOOA3do4uFM3Vqq9R+xMjVg7TcD+XTRAfzDEpi64ii/fNUfQz3V65CsTQ347csBHPF+xi9HvXkcFM3gRTsZ2aERYzo3xkBX9bXKw1Rfl3Z1qtGuTrU/PV4skZKSnUtCehap2blIZfJDsfT1V8l9IkNdbcz0dTEz0MVYV6dSdUcVITA6iQPXfTj3wJ/812lyDavZMLF3S5rWcqhQlMAvNJ4lWy4RFJkEQJ929Zg+qj26Kpo6nLvygp9+v0BxsZSarlYs+a4/lireUEhIyGDWV/uIiU6rlNgpLpLw4zcH8X8RjYGRDkt+G11psQNwdMtNbp7xRU1dzHfrRlep2Hly3Y9jG68AMGPtWEHsCAgICPwNCIJH4IOnen0HYkISCHkRVaWCB6CplxtRIYncv/bqnfP/ewzw5NYVP66c8WX8lM5o61TMKWrwkGacOvmU6KhUzp31pXefRirP7dyuDncfhXL55isWrTrN1l/GoquiU5WTjSmrZw1gyvLDvAiO4/MfD7L264GYGatutysSiRjUtiHN3ZxYsOsiT4Ji2HL+AYdu+jK2axOGtndHR1P13iwVRV1NLK/leQ9pZ+9KkUTC1afBHLjug09I7JvH6zlb83nvljR3c6yQ0MnJK2TD4dscuvQUmQwM9bWZ/Uknld31JBIpm3bdZN+xhwC0b1mT2VO7o6OiUIqKSuHrr/aTmJiJlZURK38eXiGxI5PJWL34JA9uB6GlpcHC1SNxdKm8A6PP3WC2rjgDwGdz+rzpqVUVZKXnsOrL7QD0+qQ9TTur5qIoICAgIPBu/Cv68ISHhzNu3DhcXFzQ0dHB1dWV77//nsJC1brJC/y3cW0gd5gKfR5V5Xs19ZLbSD+87o9E8m7NTj2aumBjb0puTgHXLzyv8Hw9PS1GjW4FwI7tt8jLq9jPy/TPOmFtaUhsfAZrNl+p0Fw3Fys2zBmKmZEewVHJfLr4AHHJmRVaA8DewpjN0wez8rPeVLMxJTO3gLXHbtF3/jYO3fClSMVeQ/9GYlMy2Xj6Lj3nbGH2lrP4hMSiLhbTpXFNtswcwo6vh9GijlOFxI73kxCGfbudgxflYqd7KzcOLh+rstjJzilgztLjb8TOR0NasGBWH5XFTkhIItOm7iYxMRMHB1PWrBtVIbEDsHXdZS6d9kGsJua7ZYOp06ByvXYAEmPTWDplN1KpjI79G9NrlOrpm5Xh92/2kRyXjp2rFeMXDKzSvQQEBAQE/se/IsLj7++PVCpl48aNVK9enRcvXjBhwgRycnJYuXLl//flCfzDqVZPfiAK/hsET51Gzugb6pCZlkOAbyR1GjlXei2xWEyPAY3ZsvYSpw8/omvfRhUubO7V24OjRx4SG5vOoYP3GfNRG5XnGuhrM2daT6bO3c+5qy9o2siFjm1UrwVydTBn47whfLnsCNEJ6Xy6aD9rZg2gmr15hZ6DSCSig3t12jWoxrkH/mw4fZfYlEyW7r/KrsuPGdKuIT2buWFiUDGDhH8iadl5XHocyLkHr/ANjXvzuLmhLgPaNGBg6/pYGFc86pSSnsPPu669cWCzszTim7GdaFbfSeU1gkITmL/8JDHx6WhqqjP7y250bKt6nyg/vxhmf3OQ7Ox8qle3YtmKoZhUsMnm0b13ObjjFgDT5vahedtaFZr/NgX5RSyetJPMtBxc69jx5aKBVWoccOPYQ64deYBYTcys3z9GW7dq7dAFBAQEBP7Hv9a04KeffmL9+vWEhoaqPEco+Ppvkp6UyTC3rxCJRBwO+QW9CjqHVZTl0/dw/ZQPAz5py4Tver/TWulpOYzqsYqiwmJW/vEJ9T1UP6CWcP3aKxYtPI6mpjpbto6v8B31zbu92XXoHjraGvy2bATVXSrWlyQhNYspy48QHpuKno4my6f2UamvizIKi4o5evsFW87dJyUzF5CnoHk1dKVfq/o0q+34Xlzd/i7yCoq4+TyUsw9ecfdlBMVSeWRQJJIbNgxoXZ+OHjXQULEG620Ki4o5cPEpW4/fJze/EDWxiJE9PBnXrznaWqqlBMpkMs5cfs7qjZcpLJJgbWnIwq/7UruGasYGAI8ehfH9vCPk5xdRt64dS5YNQb8C/aUAzh17zOrFJwEYO7kjwz9pW6H5byOTyVg+fS83TvtgaKLL2mNTsbKvnAW6KsRHJDOp/UJys/IZMbMnY2b3rbK9BAQ+BP7J5zXBtODfyb8iwqOIjIwMTE3L/gNVUFBAQUHBm//PzKx4So3Avx9jC0OsncyJj0gm4Gk4jdrVqdL92vZoyPVTPtw448u4b3sifgd3LmMTPTr3asjZo485uP1WpQRPu/a1OXPGmSePw1mz+gLLVgyt0J3sj4e34mVALE+eRfLNoiOsXzFK5eJ0kBsZbJo7lFmrT+IbGMPUn44ya0wH+nnVr9QddU0NdYa1d6dvi7qcefCKE7df8DIigUtPgrj0JAgbU0P6tqxLp0Y1cLE2/cfZ/cpkMgKjk7jrF8HdVxH4hMT+KTWvtoMlPZrWpqtnrUpFc0r2uPk4hLX7bhCdKLfednOx4rtxnanppLpgzS8o4pcNlzl39QUALTyrMWdaDwwr4EB444Y/SxafoLhYiqenCwsWDkCngvVoV876subHUwAMHNWSYR+rHqlUxP7fr3DjtA9q6mLmrBtTpWKnuKiYpRM2kZuVT52mroz4qmIGJAICAgIC786/MsITEhJCo0aN+Pnnnxk/frzScQsWLOCHH34o9bigjv97LPv0D64ffcCY2X0ZMbNqDxyFBcWMaP4DOVn5rNj7OfWbVit/UhnERKYwbsA6ZDIZGw9Mwrl6xSyqAaKjUxn/yR8UFUmYM68vHTpUTPRlZecz6Zu9RESnUN3Fgl+XjFDZxKCEgsJiFm2+wKV7AQB0bFqTbz/pVCEHN2UERidx/PYLztx/RVbe/25yWBjp0ay2I03dHGlW2xGL/wcTgiKJhLC4VF5FJvIoMIp7ryLeRKZKsDMzpFuT2nRvWptqNmbvtF9QZBK/7L7O41fyFE5zYz0mDWlN91Z1KhT5iopJZd7yE4RGJCMWixg/sjUjBjRTeQ2ZTMaRww/ZsP4KMhm0bVeb2d/1RrOCvW1uXnrJ0u8OIZXK6D24CZO/6flOIvbmGV+WTt0NwJeLBtBjeItKr6UKfyw4zOFfL6JvpMtv1+dh5fBu76+AwH+Bf3I0Q4jw/Dv5fxU8ygTJ2zx8+BBPT883/x8bG0u7du1o164df/zxR5lzFUV4HBwchA/Lf5DjG6+wYc4BmnVpwA97v6jy/VZ9e5BLhx/SY0Rzvlz47sXJi78+gPcVPzr1bMishQMqtcbOHbfYsd0bExM9tu/8tMIpRXEJGUyctZu0jFyaNXJh6dwBFbZhlkpl7D77kA2H7yCRSLEyM+CHz7vjUcu+QusoI7+wmKs+QZy+94qnwdFvetSU4GpjRoNqNrhYm+JsbYqzlQk2ZobvpUeOVCojJSuHuJQsgmKS8I9KxD8ykaCY5DdNQUvQ1lTHs6YDLes40aKOM46Wxu8ciYpPzmTrifucuvECqUyGpoYaI7t7MqZ3E5WtpkEuVC7d8GPVhsvk5hViYqTL91/1plED1dMQJRIp63+7zLFjjwHo08eDL6Z0Qa2Cn5e7N/xZNOsAEomUrn09mDa3zztFTAOeRfH18N8pLCim39g2fDa3T6XXUoVHV14wd+haAObt+JxWPT2qdD8BgQ+Ff/LhXhA8/07+XwVPcnIyycnJZY5xdnZGW1t+MIuNjcXLy4tmzZqxffv2Cv/hEz4s/138H4cyresyjMz02e//c5WnOT25FcicsZsxNNFjz515qGtUvP7ibQL9Yvhy9CbU1MRsPzEVSxvjCq9RWFjMp+O3EBWVSp8+Hkyd3q3Ca/gFxjF1zn4KCovp07UhMz/vXKnX0i80nnm/nyU6IR2xSMTYvk0Z16/Fe+1jU1BUjE9ILA/8I7n3KgL/qEQU/bbT0lDD0dIEO3MjDHS00NfRRF9H6/V/a6GjqUGRREJBUTGFRRIKiyUUFheTV1BEYno2CWnZxKdmkpCeTbESZz59bU1qOVhS38Wa5m5OuLvaoqnxfjKKYxMz2H7qAWe8X77Zv1Ozmkwe2gZbi4r1k8nIzOPn9Re5fkdubtCgjj0LvuqNuZnqkbG8vEKWLD7JnTtBAHz6mRdDhjar8Ofk0Z1gFszYS1GRBK9u9Zm1cECFBdPbJMWlM23gOlITM2nSvjbfb/z4ndYrj5T4dCa1X0RGcha9x7Vn8vIRVbaXgMCHxj/5vCYInn8n/5qUtpiYGLy8vGjcuDG7d+9GTa3iB0jhw/LfpbCgiIEuUykqLGbrw8XYVrDwvqJIiiWMbLmIjNQcFm0Zh2c71d3NlPHNxO34PAyj79BmTPq6R6XW8PGJYOb0vYhEsPbXMdSpY1fhNbzvBTF32XFkMvhsTFtGDmxWqWvJySvk513XOOP9EoD61W34fmI3HKwqZqqgKunZeTwOjCYwJonw+FTCEtKITEgrFX15F8QiEeZGelSzMaW2gyW1HS2p7WCFvbnRezdSiElMZ9uJ+5y9/eqNBXqTuo6M798C91oVf1/vPQ5l2brzpKbloKYmZuzQFowc1LxCIjQ1NYe5cw4R4B+HhoYas7/rTbv2qju5leD7KIy5U3ZTWFBMqw5uzFk6GLVKmDaUkJdTwFfDfif0VSzONa1ZeWAyegbvr4HtX5FIpMwZvBqfm/5Uq2fP6vOz0dSuur5RAgIfGv/k85ogeP6d/CtMC2JjY2nfvj2Ojo6sXLmSpKSkN/9mba26U5DAfxdNLQ1cGzji/ygUvwchVS541NTVaNujIad23+HKiSfvRfAM/bgNPg/DOHvsMYM/alWpzvLu7k506Vqfixees3zZaTZs/LjCBeRtmtfgi3EdWPfHVTbuvImhgTa9u1S8yaqejibzP+1K8/pOLNt2mefBcYyYvZNhXRvxUZ+m6Ou8X9teY30dOjaqQcdGNd48JpFKiU3JJCw+lcS0LLLzCsnKKyA7r+DNf+cXFqOproaWhhoa6mpoaaijqaGGpro6FsZ6WJsYYGVigLWpAeZGemhU4mZMRQiPTWXvuUec9vZ7I3Sa1XdiXL/mNKxZcaGTX1DE79uuc/ycDwCO9qbMm96TWtUr9rs1IiKZ7749SHx8BoaGOixaPIh69Suequj7KIx5U/dQWFBM09Y1mb1k0DuJHUmxhGXT9hD6KhYjUz0WbPq4SsUOwP5fzuJz0x8tXU1mb54giB0BAQGB/2f+FYLn4sWLBAcHExwcjL39n/+A/ksCVAL/ABq0rIn/o1B8bwXQaWjVFioDdBroyandd7h9/jlZ3+diYPRudtgeTatRz8OJF08j2LP5BtMqWX/w+aSOPH0STnRUKr+uvcSsbypu4jC4d2OSU7PZd/QBK3+/CFAp0QPQpUVt6tewZckfF3nwMpKdpx9y6sYLPh3Ykj7t67/XNLe/oiYW42BhjIOFcZXt8T6QSmXcex7OgQtPuPc84s3jzes7MX5AC+pXt63Uui8DYlmy+ixRsWkADOzViIlj2qKlomV1CffvBfPj4pPk5BRgZ2fCkmVDsK+E89mjO8H88NU+CguKadzclXkrhqDxDql/MpmM3xce58G1V2hqqfP9xo+r1JENwNfbnz0r5I5yX6wYgUMNmyrdT0BA4P+HvPxCNDQr1tD7XfcTqDz/mpS294EQDvxv8+jqS+YOWYOlgxk7ny6t8v1kMhmTeq0iPCCeyQv6v5cu7i99IpkxbgtiNTGbD03G3qliTTxL8PWJ5KuZe5FKZcyZ24cOHetWeA2ZTMbqTVc4dvYpABNGtWHUoIrXary93q2noazdd5PIePkB3MXOjKkj2tKigUul1vy3k5tfyBlvPw5dekpEnPw1EYmgjYcro3p6ViqiA3LXvc27vTlx3geZDMxN9Zk9tTtN3J0rtI5MJmPvnjts23oTmQzq1bNn4eKBGFVC3N+94c+P3xykqEhCszY1mbt8CJoVFF5/5eDGa2z76SwikYg5v42mVZf677ReeaQmZDDZaxFpiZl0GdGSGWvHVul+AgIfKv/k81rJtbXovhB1jaqNFr9NcVE+d8/N/0e+Jv8G/hURHgGB90Hdpq6oqYtJjEohPiIZ60qKBVURiUR0GdSUTT+e5OKRh+9F8NR1d6RZm5rc9w5k54ZrfLd0cKXWaejuyMhRLdm18za/rDpPbTdbbG0rVjsjEomY9mlH9PW02HXoHpt3e5OWkcsXn3hVql5FJBLRppErLRo4c+zaMzYfvUtYTArTfjpG07qOjOzhSdN6Tv+qpqKVQSqV4RsUw4U7/ly6F0B2rtxpUk9Hkz7t6jG4szt2lsaVWlsmk3H1VgDrtlwlNS0HgK5edflynFeFeusA5OYWsGLZGby95Tbjvft4MPmLzmhUwqDj5qWXLJtzGIlESuuOdfj2x4HvFNkBuHLsMdt+OgvAp3N6V7nYkUikrPh8C2mJmTjVtmXSsuFVup+AgICAgOoIER6B/xQzeizH70EI09eMoevI1lW+X3pKNqNaLUJSLOX3MzNwqfXu6S2hQfFMGr4BmUzGr7s/o4Zb5dKZJBIpM6bv4cXzaGrXtmHNutGoV7JW4tCpx6z74yoAndq6MXtK90odfN8mKyefbSfvc+DC0zfuY47WJgzq1JCebeqir/t+a3z+vwmNTub8HX8u3vUnLvl/TZIdrI0Z2sWDHq3rolfBequ3iU1I55cNl7n/JEy+rq0JMz/vUiG76RKio1OZP/cIERHJaGio8eXULvTs6V6p67py1peV3x9DKpXJ3dh+6P9ONTsAj70D+H7CViTFUgaMa8uE2b3faT1V2L3iFLtXnEJLV5N1l+fgWFNIZRMQqCz/5PNaybXFJyT97aYF1lYW/8jX5N+AIHgE/lNsX3Kc/avO0mFwM75eP+5v2XPx5B3cvvCC/h+34dM576fvx7I5h7l2/jmeLavz47rRlV4nISGDT8dvJTs7n6HDmvPpZ16VXuvidT+Wrj2HRCKlWSMXFn7TB50K9H9RRmxiBvsvPuH0zZfk5MlzmHW0NOjRug4DOzbE1aFqI3VVhUwmIyAikTs+YVx9GERQ5P/MWHS1NfFqUoNuLWvjWcfxnaJaBQVFHDz5mJ0H71JQWIyGuhqjBjdj5MBmlbLGfrtex8xMnwULB1TK7Q/g3LHHrPnxFDKZjK59PZg6p887W0UHv4jm65EbyMspoH1vd2b9PPydeveogs9Nf2YP/AWZTMZXv39MpyFVXyMoIPAh808+rwkubf9OBMEj8J/i6c1XzB7wC6ZWRux5saLK+/EA3L/qx4JPt2FoostO77lovQfHptioVMYPXIdEImXJb2No3Ny10mt53wxgwfdHAVi4aCCtWtes9Fr3n4Qxb9kJ8guKqOlqxZLv+mNpblDp9d4mN7+Qc7deceiyD2ExKW8er2ZnRtvGrrRrXJ3azlb/6JS3vPwiHvpFcutpKHd8Q0l6nVYGoK4mpmVDF7q1dKOVhwvamu/2OZHJZFy7HcCGHTeIT5RHjBo1cGTmxM442FW8cF8ikbJzhzd7dt9BJoO6de34/ocBmFWgR8/bHN17l40/nweg16AmTP6mxzsLk5jwJGYO+Y2M1BwatqjOwj/GoalVtZnbyXFpfNFhMelJWXQd2Zrpa8ZU6X4CAv8F/snnNUHw/DsRBI/Af4rC/CKG1JpBfk4B667MoUZDpyrfU1Is4ZMOy0iMTWfa0sF0Hdz0vay7fuU5ju+7h72TORsOfP5ONQ+/rrvEsaOP0NHR5NffxuDsYlHptV4GxDL7x2OkZ+RiaKDNN192o02zGuVPVBGZTMbjV1EcuuSD95MQJNL//QqzMNGjjYcrbRu74l7THp3/ZzvgjOw8XgTH8SIkjhdBcfgExlBY9L++P9qa6jSt50Rrj2q096yOkX7F6miUERAcz7otV3nmFwOAhZkBn41pS+d2bpUS+cnJWfy46ATPnkUB0KePB5MqWa8jlUrZuu4yh3beBmDgqJZMmNblnW8+JMdnMHPobyTGpFHNzZYVeyeiV8G6pIpSVFjM131X8uphKNXq2bPq7Ddof2CplgIC/x/8k89rguD5dyIIHoH/HD+M/o2753wZ/W0fRn7V62/Z8/Dm62xZfgaX2jb8dmr6e4ksZWflMW7AOtJTcxg/tTODx1S+Jqm4WMI3Xx/A52kENrbGrF03BlNTvUqvFxufzvwVJwkMSQCgX3d3Jn/cvsJ2x+WRmZPPHZ8wbj4J4e6zMHLzi978m1gkwtnWFDcXK9yqWVHb2YoajhZov+drAHk/n4TkLCIT0oiKT8MvNIEXwXFv3ObexsbckNYe1WjtXg2P2vZoab6/CERyajZ/7Pbm3NUXyGSgpanOiIFNGd6/aaWf98MHoSxbeor09Fx0dDSZ8VV3OnSoU6m1ioqK+WXhCa6cfQbAuCmdGTym1Tv/PGSl5zJr+O9EBCVg62TOygOTMHlPkcWy+P3bfZz84xr6Rrqsvfxdlff3EhD4r/BPPq8JguffiSB4BP5znNvlzZrpu6jVyJk1F7/7W/bMyshldOvFFOQVsXz3RBq8Qwra21w65cPKBcfQ1tHkjyNfVKoZaQkZGblM/nwHcXHp1KhhzarVI9B9h7vVRUUSNu2+yYHjjwBwcTLn+5m9qOZU+ehRWRQWFfPIL4qbT0K47RNKYmp2qTFqYhHW5oZYmOi/+bI00cfCVB8jfR3U1cSoq4lRe/1dXU2MTAbZeQVk5RSQlZv/+nsB6Vl5xCZmEJWQRkxixhtjhb/iaG1Cveo21K9ug3stO1zszN57KmVKWjb7jz/kxDlf8gvkoq9zOzc+G9Ou0imFEomUbVtvsm/vXQCqV7di3vf9KtVfByA3p4DFXx/g8b0QxGpiZszvS+de7pVa623ycgqYM3Yzr55GYGZlyM8HJld5rx2AKwfv8dOkrQD8sPcLmnVpUOV7Cgj8V/gnn9cEwfPvRBA8Av85UuLSGVn/awD2+a3ExPLv+Sysm3+Es3vv0bJLPeb9/tF7WVMqlTJz/Fb8fKNo1cGN+T8Ne6f1oqNTmfLFTjIy8vD0dGHxksHv7Lb24EkYS9acJTU9F01Ndb74pD19u7lXef1Ucno2/mGJvAqL51VYAq/CEkjNyK2y/TQ11LCzNMbeypgajubUr25L3WrWGP1fe/cdV2X5/3H8xd5DQBkKgrjFiSP33rlK0yzT9GtqaY5yz4Y5c8/MNC1Harg1R87cinskCqLsIUOQczjn3L8/SH6ZZqDAOQc/z8eDB3Cfm/v6eIt4vbnu67ry8bGq+IRHrAs6w/bfLqFWawCoVM6Twf2aUancy63eB1mLWXwzdTtXrzwAoGOnGgz6uDmWLzka9TDhEROH/sztG5FYWVswcWZ3atV/9cccVRmZTP7fSi6duoO9kw2z1n+Mb1mPV77uf7l77QHD20xD9TiT9z5/k15j8mYxEiFEFkPur0ngMU4SeMRraXCzrwm5HM6IhX1o9e6r74+TE+EhMQxoMxtTUxN++H1Mnv0WOvR2DJ+8twytVseUOe9St3H5V7rezRuRfDZiHRkZmTRvUYkxYzu88kIAiUlpTJu/J3tJ5Do1/Bj6UXNKeOZu759XoSgKcQ8fERmXQtzDR9lvsYlZ71PTMtDqdGi0OrRaXdbHGh0KYG9rhaOdFfa21n+9t8LRzhrPok54uzvj7e5MMReHAlswISYuhXW/nmHX/svZc4IqlvWkT4961Knh90qbv+7ZfZmlSw6Qnq7G1taSzz5vR5OmFV661sj7iYwbvJaoB4k4Odvy5fz3KB9Q4qWv90SmWsNXH//I2cM3sbGzYtraAZSr4v3K1/0vj5LTGdJiKlGhcdRsXokv1g155ZXlhBBPM+T+mgQe4yQbj4rXUp1WVQi5HM6pvZcKLPD4lHanRoOyXDj+J1tXH2fAhLz5rbBfGXfefr8ev/x4nEXTdxFQvSQOji8/qlC+gheTpnRhwrhNHDxwDUcHaz4Z0vKVRmRcnO2YMfFtNu88z/Ifj3L6Qii9B6+ia8dAPuj2BnYFMNHbxMSEYi4OFHPJ/7kd+SUkNJZftp/jwNEbaDRZj9BVrlCcPj3qUbNqyVf6O0pIeMS3s3dz+tQdACpWKs6YsW9S/CVWdHviavA9vvx8A8lJ6XgUL8I3i3pR3Mf1pa/3hFajZcbwdZw9fBMrawu+WNG3QMKOVqtj5sCVRIXG4e7jyuhl/5OwI4QQRkB+UovX0httqwJw/verZKSpCqzdt/o1AmDPhlMkJTw7x+Rlvde/McV9XImPTWHhtJ286sBtnTr+jBzVHoCgoPMsX/b7K1/T1NSEdzrWZNX8PtSq5kumRsv6X8/Qc+D37Nx3Ge2/zIF53el0CifO3mHYxI30HfYje3+/hkajo1qAN/O+6s6iae9Sq5rvK4WdI4dv0K/vCk6fuoOFhRkfDWjKvPnvv1LYObj7EmMG/UhyUjplKngx94d+eRN2tDpmfb6BP367grmFGROX9KZy7VKvfN2c+HHqVs7sv4KltQUTVg3EocjLL+whhBCi4MgIj3gtla7ig0dJN6LvxXP24FUadgwskHZrNChLuare3Lp0ny0rj9Dvr1DxqqxtLBn11VsM77uSI/uuUqdhWZq3q/pK12zVujJqtYa5c/ay6ZczmJub0e9/jV957o1PCRdmT+nKyXN3WfTDIR5EPmTm4t8I2h3Mxx82oUYVnwLZH8nQpaer2X/kOr9sP8f9yKzV3sxMTWhcrxzvdAyk4ivM0XkiJeUxixbs4+DB6wCULuPOmLEd8HuFZcl1Oh1rlx1i3cqjANRvVoFRX76Ftc2rb0Kr0+mYN/YXjuy8iJm5KeMXfUBgo3KvfN2cOLT5NL8syNo3aPj83gWypL0QQoi8IXN4xGtrxeTNbFm8j6Zv12b08v8VWLtPNiK1trVk9eFxOL3C8s//9POKw6xZdghbOyuWbhiEh9erz5HZGnSOhQv2A1mT1wcPaZlnj/FkZmr5dfcFftx4kkd/jbSV9XfnnY41aVq/3CsvmGBstFod5y/f47dD1zh68jaqvxYisLezokOrKrzVvgbuRV/9Z5eiKOzfd5Xly34nKSkdU1MTer5Xl/d7NXile67KyGT2lCCO7r8GQPc+DejzSfNX3lAUssLOwom/snfjaUzNTBm34H3qt678ytfNiVsXwhjZcVbWPl5D29B34lsF0q4QrytD7q/JHB7jJIFHvLaun7nDiHYzsHO0YcPNb7HIw/1QXkRRFIZ0ms+d6xH0+Lg5vUe0ybNrazVaPv9oFdcv3SegeklmLu+TJ+Fka9B5Fi3ch6JAw4blGDu+Q57uqZOUnM7qjSfYtf9Kdie/qKs9XdrVoGPrKjjm8waS+nb3Xhy/HbrG/iM3iP/bcto+xV3o0q46bZsFYGv76iMkAGGhccyf91v2JqI+JV0ZNao9FSoWf6XrJsanMmXEem5di8Dc3Iyh4zvQqmP1vCj56bBjasLIOT1pkgdLWudEQlQSn7b8hoToJOq0qsKktR/LvB0h8pkh99ck8BgnCTzitaXV6ni/8igexqbwzeZh1Gjycpspvow/9l3h64/XYGNnxY9HxuHgbJtn1456kMigd5fyOF1N38Et6P5hwzy57pEjN5k2dTuZmVoCKpfg66ldccjjIJKc8pjtv11iy64LJD5MA8DayoI2zSrRsnEFKpUrXmAroeUnjVbH9VuRnDh7hxNn7xB2PyH7NUcHa5o3rEDrppWoUMYjzx7ve/xYzU9r/2DTL2fQanVYWZnTq3cDunat/cojaTevPOCr0RuJj0nBwcmGybN7ULmGb57UrdXqmD9+M/s3n8XU1IQRM7rTvEvBPIKqeqxmVKfZ3LoQhk85T+buHYNdIQ/fQhgCQ+6vSeAxThJ4xGtt/vC17Fl7jDf7NmHwzJ4F1q5Op2Nwx3mE3oyi+6Bm9PmsbZ5ef9/2YL79YitmZqbM+aFfniwDDHDx4j0mTdhCWpqKkiXdmDqtG56eznly7b9TZ2r4/dhNftl+jpDQuOzjRV0daFq/LE0blKdiWU+jmuuTocrk7MUwjp26zYmzd0hJzch+zdzclLo1/WnTtBJvBJbK00f5FEXh5IkQFi7cR2xMCgD16pdh8OCWuHu8/Ea1T669a8s5ls7ag0ajpURJN76c35Pi3q++OAFkjVjOHbuJg0Hns0Z2vn2XJh3yZtTovyiKwsyBKzm05QwOReyYv28sXn7FCqRtIV53htxfk8BjnCTwiNfauYNXmdB9Ac5FHfj5ykzMzAtuzsiTUR4rawu+PzAat1fsfP6doihMHf0Lxw5ex7WoAwvXDsC1aN4sx3z3bixjR/9CfHwqTk42fPHV21SunD9LAiuKwoUr4ew9eJVjp0NIf6zOfs29qCON65UlsEpJAsp74WBvnS81vKxHaSqu3ozg0rUHXLp2n5sh0dlLSQM42FvzRqAf9Wr6U7uGX77Uf+dOLMuWHOTChTAA3N2dGPxpS+rVy5tNPxdO38n+HReBrMUJPpvcGbs8+nNoMrXM+nw9R3ddwtTMlNFzetKo/astxJEba2ds5+dZOzE1M+WbTcOo1ujV9rcSQuScIffXJPAYJwk84rWmydTwXsAokhMe8fXGT6nZPKDA2lYUhc+7L+b6hXu06lqL4dPfydPrpz3KYFif7wkPjaNcpeLMXvEhlnk07yYuLpVJEzbz55/RWFiY0f+jJnR5q1a+Pm6mUms4ExzKoeO3+ONMCI8zMrNfMzGBUiWLUrlCcapULEGViiUo6mpfYCNAj9JUhIbHExoez917cVy9GUlIaCw63dM/Xj2KOdGwTmkavlGGgArFMc+nuSCJiY9Y9cNR9u65jE6nYGFhRtdutXnv/XrY5MFqadGRD/lq5EZCbkZhamrCh4Nb0O2D+nl2vzPVGqYP+5kT+65ibmHGmPnvUb9VwSxQAHDwl1PM+vgHAIbO6UXbD/LmsVAhRM4Ycn9NAo9xksAjXnuLR69jx8rDNH/nDUYu6Vugbd+4EMaIdxZjYmLC4p3D8SvnmafXj7ifwKcfrOBRymOat6/KyC+65FmnNCMjkxnTd3L0yE0Aatb0Y9SYN3F1tc+T67+ISpXJ6QuhnDh7h0vXHxARlfTMOfZ2VpTwLEJxT+fs98U9i+DmYo+drSW2tlY5ChyKovAoTUViUhoJiWkkPHxEwsM04uJTCbufQNj9eOL+ZU+l4p7OVK3kTdVKJahasQSe7k75GsJUqky2bD7Lup9P8viv0bAmTSrwv4+a5Nmjh+dPhjBt/GZSkx/j5GzL2GndqJ6H++CoVZlMHbyWM4duYGFpzoTFH1C7aYU8u/5/uXLiT8Z1nUemWkO3Ia3pN/ntAmtbCJHFkPtrEniMkwQe8dp7slqbjZ0V62/MxtrWqkDbnzp4Lcf3XqZmo3J89UPeL48dfOYu4wavRafV8b+hrej2Qf08u7aiKOzYHszSJQdRqzU4Otrw+ch21G9QNs/ayImEh4+4ciOCy9cjuHL9AbefM7ryPNZWFtjZWmJna4WFhRkajQ6NRotGqyNTo0Wr0fFYlYn6r5XjXqSoqwN+Pq74+rhRoYwnVSuWwK0Awh+AWq1h757LrF93ktjYrHk65cp78vHHLQionDfztzSZWtZ+d4iNq46jKAplK3oxcWZ3iuXhHK601Ay+GLCKK2fuYmllzqRlfQhsWDD77AA8CIlheNvppD5Mo0GHGoxb+VGeLKkthMgdQ+6vSeAxThJ4xGtPURT6BI4jJjyBsSv607hLrQJtPzIsngFtZ6PJ1DJ1dX9q5ENY2LbhFEtm7cHExIQv5/Wkdh63ce9ePN98vZ2QkBgA2r9ZjUEfN8+Tx6deRoYqk8joJCKikngQ+ZAH0Q+JiMr6PCk5PXvp69yws7XEtYg9rkXscHWxx6WIHT7FXfDzccPX21Uvc4hUqkx277rEhvWniI9PBaBoUQf69W9C8+aV8uwRw4j7CcwYv4Vb1yIAaNslkI9Hts2zRyQBkhIeMbHv94Rci8DGzoopyz+kyhv+eXb9/2w/PpXhbacTFRpHuRq+zNz2OVZ6+v4V4nVnyP01CTzGSQKPEMDqqUFsmLuHOq2r8MXPgwu8/WVfb2Pb6uOUquDJgq3D8nyfD0VRmD91B3uCzmNrZ8XcVf/D1z9vV5xSqzWs+uEom345jaJACW8XPvu8HVWq5M+CBq8iM1NL+mM1aekqHqWrSE9Xo87UYGFuhrm5Gebmplkfm5liaWWOi7Md1nnYuX9VKlUmO3cEs2H9KRITs5bvdnNz4N2eb9C2XdU82yNJURQO7LrE4hm7eJyuxt7BmmETOtKwRaU8uf4TMQ8SGd9nBRFh8Ti52PH1D/+jdB6tLJgTGekqxr49lxtn7+JR0o25e8ZQpJj8HyGEvhhyf00Cj3GSwCMEcO9WJAPqT8HUzJS1F6fjmg9LLb9IysM0+jWfwaOUx3w8uTMdeuXdY2dPZGZqGDNoDVeD71HU3Ym5q/pR1D3vVoZ7IvhCGNOn7cwecWjarAL9P2qKez609bpJTX3Mzp0XCdpyjoS/5g0Vc3ekZ8+6tG5TBcs83Dw37VEGi6bv4vc9lwGoEujLyC/folgeriYIEPZnNBM+XEFCTArFvJyZ+uNHlPArmqdtvIhWo+WrPss4tfcS9k62zN07Gu8yeTuXTgiRO4bcX5PAY5zk4WQhgJLlvKhYxx+dVsfen44XePuORezoPaINAKu/3UtiXEqet2FhYc6kWd0pUdKNuJhkxgxaQ0Jcap63U72GLytW9qP9m9UwMYFDv9/gw97fsebHY2T8bWU1kXMREYksXLCPHu8s5vvvDpOQ8Ihi7o6M+Kwta9YOpEPHGnkadq5dCueT95bz+57LmJqZ0ntQM6Yv7Z3nYef6hTBGvruEhJgUSpZx59tfBhdo2FEUhUWj1nFq7yUsrMyZ8vMnEnaEEKIQkhEeIf7y+6bTzBy0EjdPZ34Mnlage/JA1o7yw7su5PaVBzTpUI3Rc9/Ll3ZiopL4rN8PxMUkU6KkGzOX98mzPXr+6fbtaJYsOsDly/cBKFbMkY8GNKVJ0wpGtWmoPiiKwpXL99m06QwnT9zmyU/qUqWK0e2d2jRtVjFPNygFyHisZvWSg2xdfxpFUXD3dGb01LepVNUnT9sBOP37daZ9+hOqjEwqVC/JFyv64uBsm+ftvMhPM3fw08wdmJqaMH7VQOq3L5hNTYUQL2bI/TUZ4TFOEniE+ItalUmvKqNJTnjEpDWDqNeu4Ds/t68+YNhbC9DpFL74vi+1m+TPcrxRDxIZ+dHqAgk9iqJw9MhNli37ndiYrJGrsmU9eKd7HRo1Lp/n85WMXVxcKgcOXGXfb1cIv5eQfbzOG/5061abatVL5ktYvHg2lHlfbSMq4iEArTpWZ8CI1tg72OR5W9vX/MHyr7eh0ynUbFye8Qt7YW1bsAsE7FlzjPkj1gIwZNZ7tP+wcYG2L4T4d4bcX5PAY5wk8AjxNyu/2MKmhb9Ro2lFvtk0TC81rPhmB7/+cJSins4s2/MZtvm0+ldBhh7Immj/y8bTrF93EpUqa5U0d3cn3u5ak7btqmJbwMuBGxKVKpM/jv/Jvt+ucP58WPaS2lZW5rRsVZm3u9bCx8c1X9pOT1Px/fx97NpyDoCi7k4Mm9CRmvVK53lbWq2OFdN2sG111mOjrbvVZvCXb2GexyNV/+Xk7ot81WcpOp3Cu5+1p/fYTgXavhDixQy5vyaBxzhJ4BHib6LC4uhbawKKovDDma/xKpW3K5nlREa6moHtZhPz4CEdP6jPoEmd862tgg49AElJ6Wzfdp6tQedJTn4MgJ2dFW92qE7nLoEUe01Wx1KrNZw7F8qxo7f44/ifpKWpsl8LqFyC1q2r0LhJeezs8i8Injn+Jwun7SQ2OhmAN7vWou+QFtjlQ8jOSFczY/jPnDp4HYAPR7aj20dNCvzRxst/3GL8O/PJVGlo9V59hs/7QB6vFMLAGHJ/7Ult0dFxBR54PDyKGuQ9MQYSeIT4hwnd53Pu4DW6DGzBgK/f0UsN54/dYsKH32NiYsI3az6iWt28/237E38PPZ7FizB9aW88ihfJt/aeUKky2b/vKps2neHB/UQATEygSlUfmreoROPG5bHXw942+UmlyuTsmbscPXKTkydDSE9XZ7/m7u5Eq9YBtGpVGa98vv/xsSksnb2H43+FD8/iRRg2sRPVavnlS3sJMclM+WgVIdcisLA0Z+TsHjRsVzVf2nqRP4PDGNNlDumPMqjbtioTVg0s8Ll6Qoj/Zsj9tSe1NWowCXPzgvs/SqPJ4OjxLw3ynhgDCTxC/MOZ/VeY9O5CbB2s+enyTGwd9NPpnj9+M3s3nsbV3ZElO0fgWMQu39qKjnjImEE/EhXxkCKu9kyc1T1fJqo/j06ncOpUCFs2n+Vi8L3s4xYWZtR5w5/mzSvxRt3SeboKWUFRFIX79xO5cD6M4OAwzp0NfWqlOjc3Bxo2KkejRuUIqOydZxuF/hutVseOX87w49LfSU9TYWpmSpd33+CDgU2xzqdNNkNvRjK5/yriopJwcrFj8rI+VKjhmy9tvci9W5GM7DCLlMQ0qtQvy1cbPpWNRYUwUIbcX5PAY5wk8AjxDzqdjv51JxNxJ4aPp/eg4/+a6aWOjHQ1QzrP48HdOOq2rMTEJb3z9dGbhLgUxg/5idDbMZibmzFkbHvadA7Mt/aeJzo6iUO/3+DggWuEhsZlH7e2tqByFW+qVStJteo+lCnjYZCLHSiKQnR0MpcuhnPhQhgXg+9l75fzhLu7E40al6NR4/KUL++V7yHniT+vR7Dgm53cvhEJQPmAEnw6vgP+ZT3yrc1jey4zZ/RGMtLVePsX44sVffHMp7lILxJ9L57P2s8kITqJstV9mf7rCL39IkMI8d8Mub8mj7QZJwk8QjzH9u9/Z8mYDRQvVYwVp77E1FQ/neuQqw8Y3m0RmkwtQ75+m3Y93sjX9h6nq5g9ZWv2o04du9dmwPA2BT6pHODOnVh+P3iN3w9eJzb26X2J7OysqFzFm6rVfPD3L0bJkm64utoX6FwMrVbH/fuJhNyOJiQkhpDbMYSExJCamvHUeRYWZgQElKB6DV9q1vKjbFmPAq0zKfERP313mF1bzqHTKdjZW/Ph4Oa0e6tmvoVGrVbH2rm/sXHZ7wBUq1eacQt74eBUsMtOAyREJfF5h5lEhcXjW8GLmds+x9HFvsDrEELknCH312TRAuMkgUeI50hPzeD9KqNIT83gqw1DqNWist5q2bziMCtn7MLK2oKF24bh7Z+/CynodDrWrzzKmmWHAKha04/x07vhlI+P1L24HoXQu7FcvHiPi8HhXLoU/tQE/yfs7a0pWdKVkr5u+Pi4UayYA07Otjg721GkiC0ODjY5Hk3RanU8epRBWpqKlOTHxMQkEx2dTHRUEtHZHyejVmue+Vpzc1PKlPWgRg1fqtfwpVKl4np5HC/jsZpffz7JpjV/kP7X/WrSujIDRrTGxS3/FqZITU5n5vB1nDt6C4C3+jWi78h2epkrk5L4iM87zCL8VhSefkWZvWMkrh7OBV6HECJ3DLm/JoHHOEngEeJfLJ/wC0HLDhDYrBJTfxmqtzp0Oh3j+6zg4okQSlXwYu7mwVhaWeR7uycO3WDmpF95nK7G3cuZKXPepVSZ/Hv8Kae0Wh13QmK4eDGcq1cfcO9ePJERD7OXcv43pqYmODrZYGNtiYkJmJqZYmpigqmpCaampmi0WtLSVKQ9Uj01z+ZFrK0t8PcvRuky7pQp40HpMu74+hbN8w1Bc0Or0bJvx0XWLDtEYnwqAKXLe9J/aCuq1S6Vr22H/RnNlwNXExWegJW1BUO/6UbTjvrZzPNRcjpj35rL7Uv3cPN0ZvauUXj4uOmlFiFE7hhyf00Cj3GSwCPEv/j7EtVLj07Cr2IJvdUSH53MJx3mkPIwnVZdazFsWrcCeSwqLCSGKSPWExXxECsrC/oOaUHH7rX19ojfv1GrNTx4kEhYWDz3wuK5H55A4sM0kh6mkZSU/sxjZjllZWWOg4MN7u6OeHg44e7hjIenEx4eT96cDWYukaIonD95hxXzfiPsTiwAHsWL0Ofj5jRuVSnf/87++O0Ks0duICNdTbHiRZi0tDf+FYvna5v/Ji0lnXFd53HrQhhObg7M2v45PmU99VKLECL3DLm/JoHHOEngEeIFpvZbzrFt52nYKZDxKwfotZbzx24xqd9KdDqFj8Z3pMuHDQuk3ZTkdKaP38L5kyEAVAn05bMpnfHwyv+lq/OKRqMlOfkxSQ/TUKk1KDoFrU5Bp9Nlf2xmZoqdnRX2dlbY2Vtha2ul15GanFIUhUtnQ1mz/BDXLoYDYO9ow3v9G/Nm11r5/jhdplrDqlm7CVp1DICqdUszdv77OLno5xHItNTHjO82n5vn7uJQxI4ZQSMoFeCtl1qEEC/HkPtrEniMkwQeIV4g7EYEAxt+AcCyY5PxraCf31g/EbTqGN9N3Y6pqQlfft+PwEblCqRdRVHYufksK+btQ5WRiY2tJR8Nb03bLoGyaaMeXToXytrlh7hyIWs5bwtLczp0q8W7/RrhWAALBMREPGTapz9x61JW0NLnfB3Imns3oft8rp+5g72zLTOCPsO/soQdIYyNIffXJPAYJ8N4FkMIA+VboTgNO2Utzfzz7J16rgY692lAq6610OkUpg39iQd3YwukXRMTEzp0q82yDR8TUL0kj9PVzJ+6gwmf/kT8P1ZQE/lLURSuXAhj5EerGDVgNVcu3MPCwoyO3WuzettQBoxoUyBh59TB6wzuOJdbl8Kxd7Rh0tLe9B/bQW9h5/GjDCa+uyAr7DjZMm3LcAk7QgghABnhEeI/Gdooj1qlYVzv77h2LpTivm7M3TKkQJf71Wp1bF1/ilWLD5Kp1mBnb837A5rQoVstLCyMb3NQY5GZqeHY/usEbTjFn9cigKwlr9t0rkH3DxtS1N2pQOrQZGpZ/e0etnx/BIByVb0ZO/993Eu4FEj7z5ORpmJijwVcOXkbO0cbpm0ZTtnqvnqrRwjxagy5vyYjPMZJAo8QOWBIc3kAkhIeMbTLfGIjk6hevwxfrexX4L9ZDw+NY9bkoOzOt2cJF/p92pIGzSrIY255KOlhGru3nGPHprPZq65ZWJjRqmN1evRtRDGPggk6AFHhCcz6bD03grMeoevyYUM+HNkOCz0su/1ERpqKST0XcvmPP7F1sGbaluGUq+Gnt3qEEK/OkPtrEniMkwQeIXLg76M8S45MolQl/a3Y9sTdG5F81n0xGelq2vesyydfdCnwoKHV6ti3PZg1S38nMeERABWqeNN/aCsqVfMp0FoKm7CQGLb9cob9Oy6S+dd+Py6u9nR4pzbt3grEuQA3z1QUhQNB51n6xVYep6mwc7BmxMzu1GsZUGA1PE9a6mMmvbuQa6dCsLW3ZurmYVSomb9Lbwsh8p8h99ck8BgnCTxC5NA3/b7j6LZz1GoRwFcbPtV3OQD8se8KUz9Zi6IodB/YjN6ftdHL6MrjdBWb1vzB5rUnUP21h029JuV5/6Mm+JeT5YBzKuOxmiP7r7En6Dw3Lt/PPl62UnG69HiDhi0rFvhjg6nJ6Sya+CtHd18CIKCWH5/P6qHXR9gAUh+mMf6d+fwZHIadow1TNw2lfKCEHSEKA0Pur0ngMU4SeITIoci7sfSvNwmtRseMoBFUbVhe3yUBsPPnEyyeHATAe0Na8v7QVnqrJSEuhbXLD/PbtgvZG4FWq+VHl551qd2gjMHt32Mo7tyKYvev5/l9z2XS01QAmJmZ8kbjcnTpWZeAaj56CbKXT91h1ufriY9OxszclPc/bUW3AU31vvdQUnwq47rO5e7VBzi62PHN5uGUriIjikIUFobcX5PAY5wk8AiRC4tHr2PHysOUqVaS+fvGGkwHPuiHo3z3zQ4APhjRhnc/bq7Xeu7djeXnFUc4dvA6Oq0OgBIlXenSsy4t2lfF2sZSr/UZgvDQOI4fvM7RA9cIvR2TfdyzeBHadgmkZYdquLg56KW2TLWGn+bvY9N3h1EUBa+Sboya8y7lquo/VCREJzH2rbmE/xlFkWKOTPt1BL7lvfRdlhAiDxlyf00Cj3GSwCNELiTFpfBhzfE8TlMxdkV/Gneppe+Ssm367hA/zNwNQL/R7enav4l+CwJio5LYtvE0e4IukPYoAwAHJxtavlmNxi0DKBdQ/LVZ4EBRFO7djePYgWscO3ide3f+f0lxc3Mz6jUtT7u3alK1pq9eg/SNC2HMH7+Ze3+FsNbdajNgQkds7Kz0VtMTsQ8SGNNlLpGhsbh5FWH6ryMoUdpd32UJIfKYIffXJPAYJwk8QuTSz7N2snbGdjx93fjuxJd6XaHqn9YvPsCaub8BMGBCRzr3aajnirKkp6nYtz2YoPWniI54mH3c3cuZxi0DaNwqAP9yHoUu/DxKfczlc2FcOH2HC6fvEhGekP2aubkZ1euUomGLStRtVA5H54JbWvx50h9l8OOcvexYewJFUXBysWPwl2/RoE0Vvdb1xIOQGMZ1m0fs/QQ8Srox/dcReJR003dZQoh8YMj9NQk8xkkCjxC59PhRBn1rT+BhbAoDp3an8wD9Pj72T2vn/ca6RQcAGDipE50+aKDniv6fVqvj7B+3ObT3CqeO3iLjsTr7tRIlXanfrCI16vhTsUoJLK0s9Fjpy9FkarnzZzTnT4Zw9sRtbl55kD2XCbKWkw6sW5oGzSvyRqNyODja6LHa/3f+6C0WTNhMbGQSAC3eCqT/2A44FrHTb2F/uX3xHhN6LCA5PpXi/u5MDxpBUa8i+i5LCJFPDLm/JoHHOEngEeIl7Fp9hIWf/4ytgzUrTn6Jq4ezvkvKpigKq2fv4Zflh4CshQze+7SlwY2eZDxWc+b4bQ7vu8LZP26jVmmyX7OysqBSNR+q1ylF9dql8C/nYTDzpf4u+WEaN6484Prl+9y4fJ9b1yKyV6l7okRJV6rX8adGHX+q1vTFzt5aT9U+KzU5nRXTdrJ/81kAPLxdGPLV29RoUFbPlf2/i0dv8kWvxTxOU1G6ig9fb/wU56Ly81uIwsyQ+2sSeIyTBB4hXoJWq2NY62ncvniPxl1qMXZFf32X9BRFUVg7fx/r/xrpadKxOsOndTPYUZP0NBWnjtzi3MnbBJ++m72nzxN29taUKuuOXxl3/Eq7U6qMB76lixXY4gcZj9XcD4vnfmg84WFxhIfGERYS+9Qjan+vtUqgL7UblKFm3dIU83QukBpzQ6fTceDX8/wwcxfJiWmYmJjQsXd9+oxoi7Wt4SwocWz7eWYOXEmmWkO1huWZuGYQdg6GMSomhMg/htxfk8BjnCTwCPGSbl+6x9CW36DTKUzdNJTAppX0XdIz9mw4zeIpv6LV6KgY6MvEJb1xdi24DStfxpPJ/cGn73DxbCiXz4dlL9X8dyYmJnh4OVPUwwm3Yo64FnXApagDbkUdcXGzx9beCktL86w3a4vsj3WKglqViSpDg1qViVqtQa3S8Cg1g4S4VBLjn7w9IjE+ldioZGKikv61Xm9fNypW9aZCZW8qVvXG29fNIEejngi5+oDFU4K4eTEcAG//Ygz9piuVAv30XNnTdq06wqJR61AUhQYdazBqaT+DDexCiLxlyP01CTzGSQKPEK9g2fiNbF1+EE+/oiw7OhkrA1xuOfiPP5k6eC1pqRl4eLvw5ff98PYvpu+yckyTqeVeaByht2MIvR391/uYZ0aB8puTsy3efkXx8XPD268oJf2KUqaiF45O+l1sIKdSk9L5cc5edq8/haIoWNta8t6QlnTq3cCgFt5QFIV13+5i7fTtALTr3YhPZvbU+94/QoiCY8j9NQk8xkkCjxCvID01g4/qTSI+Komen7Xng7Gd9F3Sc4WHxDC5/w9E30/E3tGG8Ys/oFrd0vou65UkJT4iPDSehLhU4mNTSIxP/dvHj1A9VqNWa1CpNGSqNc98vampCZZWf438WJtja2eFi5sDrm72uLhljRa5uDngVtSBEr5uOBvIBP7c0mq0/LbpDD/O2UvKw3QAmnSoRr/Rb+Lm4aTn6p6mydSwePR69qw5BkDPz9rTa0xHg5t/JoTIX4bcX5PAY5wk8Ajxio7vOM/XHy7H3MKMJUcm4VPWU98lPVdSwiO+GrSa6xfuYWZuysAJnWj/Xt3XojOp0+nQZGpRqTSYmphgaW2OublZof6zK4rCyQPXWDVrNw/uxgFQsow7H0/uQpU3/PVc3bPSUh8zte9yLhy6jomJCQO/6U6n/s30XZYQQg8Mub8mgcc4yTMCQryi+m/WoHbLymgytXw7eBVajVbfJT2Xs6s909YOoEmHamg1OhZPCeLrT9aQmpSu79LynampKZZWFjg42mDnYI2FhXmhDjshVx8w+r1lfDXoRx7cjcOxiC0DJ3Zi0fbhBhl24iIS+az9TC4cuo6VrSWT1gySsCOEECLPSOAR4hWZmJgw5Nv3sXO04daFMH5ZsFffJf0rSysLRs3pyUfjOmBuYcaJfVf5+M05XD59R9+liTwQH53Mt6M28GmXBVw5cxdLK3O6D2rGD7+PpVPvBphbmOm7xGeEXA5naKtphF2PoEgxR2ZvH0ndttX0XZYQQohCRAKPEHmgqFcRPp7+LgA/z9rJnSv39VzRvzMxMaFL30bM3TSY4n5FiY9OZmyv5ayZ95vBjk6JF0uISWbZ19vo13w6B349j6IoNO1YnRX7R9Hns7bYORjO3j9/d2b/FT7vMIvEmGRKlvdi/r6xlKlWUt9lCSFEobFkyRL8/PywtrYmMDCQY8eOvfD8I0eOEBgYiLW1NaVKlWLZsmVPvX7t2jXefvttfH19MTExYd68ec9cQ6PRMGHCBPz8/LCxsaFUqVJ8+eWX6HS6vPyj5YoEHiHySLNudaj/ZnU0mVpmfbwStSrzv79Ij0oHlGDh1qG07FoLnU5h/aIDjOq5lJgHifouTeRQXGQSS6YE8WHT6WxbfRy1SkPFQF/mbRnCqDk9KeZVRN8lPpeiKGxb8TtT3ltERpqK6o0rMGf3KIqVcNV3aUIIUWhs3LiRYcOGMX78eIKDg2nYsCFt27YlPDz8ueeHhobSrl07GjZsSHBwMOPGjePTTz9ly5Yt2eekp6dTqlQppk+fjoeHx3OvM2PGDJYtW8aiRYu4ceMGM2fOZNasWSxcuDBf/pw5IYsWCJGHkuJTGdBgCsnxqbzzaRv6TnpL3yXlyJFdF1kwfgvpjzKylyvu3KehQT4CJSDmQSK/LD/Evs1n0WRmjcpVqunHe0NaUK1eGYOen6RWZbJo1Dr2/fwHAK161uPTb9/H3MJwlsYWQuiXIffXntQWEx1X4IsWuHsUzdU9qVOnDjVq1GDp0qXZxypUqEDnzp2ZNm3aM+ePHj2a7du3c+PGjexjAwcO5NKlS5w8efKZ8319fRk2bBjDhg176vibb76Ju7s7K1euzD729ttvY2try9q1a3NUe16T/2GEyEPObg4MnfM+X36wlM2LfuONNlWpWNvwJon/U+P21ShXxYdvR23g6tlQVs7Yxf4t5/jkiy5UqWP49b8u/rxyn6AfjnJsz2W0mqxHA6rU8afn4BZUecPfoIMOQEJ0El/1WcbNc3cxNTWh3+S3eevjlgZftxBC/NO7rWdjbmZVYO1ptFkbcKekpDx13MrKCiurZ+tQq9WcP3+eMWPGPHW8VatWnDhx4rltnDx5klatWj11rHXr1qxcuZLMzEwsLHK2+XODBg1YtmwZf/75J2XLluXSpUscP378uY+/FRQJPELksXrtqtOie10ObDzJjIHfs/jQROyNYHNKD28XZvw8kINB5/l++i7CQ2IY/d4ymnSszv9Gt8fV3bD2bHldKIrC+aO32LziMJdO/f/iEtXqlabn4JZUrl1Kj9Xl3K0LYXz5wRISopOwd7Zl3PcfUaNJRX2XJYQQRsXb2/upzydPnsyUKVOeOS8+Ph6tVou7u/tTx93d3YmOjn7utaOjo597vkajIT4+Hk/PnG27MXr0aJKTkylfvjxmZmZotVqmTp3Ku+++m6Ovzw8SeITIBwO/6c7VU7eJvhfP3KE/MmHVQKP4LbapqSkt367FG80rsXrOHvasP83h7cGcPnidnoNb0KFXfaysc/YbHvFqNJlaju25zOYVh7h7IwoAM3NTGrevRpcPG1I6oISeK8y5g7+cYt7wNWSqNPiU82TK2k/wKlVM32UJIcRLW//b53p4pG0G9+/ff6rd543u/N0/+x6KorywP/K88593/EU2btzITz/9xLp166hUqRIXL15k2LBheHl50bt37xxfJy9J4BEiH9g72TJ2xUd81n4Gf+wMJmjZAd4a1FLfZeWYg7MtQ758mzbv1GHx5CBuXQpn5Yxd/LryCF37N6Fdz7pY21jqu8xCKSo8gb0bT7N/y1kexj8CwNrWkjbv1KFL34YGuxDB82gyNaz6eitbFu8DoE7rKoxa1g87Bxs9VyaEEK/G2sayQP8fVGdmteXo6JijoOXm5oaZmdkzozmxsbHPjOI84eHh8dzzzc3NcXXN+aIyI0eOZMyYMfTo0QOAypUrc+/ePaZNmyaBR4jCplwNXz76qhtLxmzg+ylb8K/sQ9UG5fRdVq6UCSjBnE2fcODX86xbtJ+YBw9ZMW0nm747zNv9G/Nmz3pY20rweVWZag2nDlxjz8bTBP9xO/t4ETd7OvSqz5vv1cPB2fAfi/y7uMiHTOv/Hdf/2uOpx/C2fDC2E6amsjioEELkN0tLSwIDA9m/fz9dunTJPr5//346der03K+pW7cuO3bseOrYvn37qFmzZo7n70DWSm7//FlvZmam12WpJfAIkY869GvKzfOh/L7pNN/87zsW/T6Bokb0G3rIesytVddaNOtUg4NB51m/5AAxDx6ycvouNn93mLf6NaZt9zpG1yHXN0VRuHkxnKO7LnF4RzBJCVmjOSYmJtRoUIa2Pd6gTrOKRrlS3vlD15g5cCXJCY+wdbBmxILeNOgQqO+yhBDitTJixAh69epFzZo1qVu3Lt999x3h4eEMHDgQgLFjxxIREcGaNWuArBXZFi1axIgRI+jfvz8nT55k5cqVrF+/PvuaarWa69evZ38cERHBxYsXsbe3p3Tp0gB06NCBqVOn4uPjQ6VKlQgODmbOnDn07du3gO/A/5NlqYXIZxnpKka0m8Hdqw8oV8OXWTtGYmllvPNgNJlaDm49z4YlB4m+n7Vnj6WVOQ3bVaXdu29QoXpJo5ivpA+KonD76gOO7rrEsd2XiI1Myn7NpZgjrbrWonW32nh4u+ivyFeg1er4eeYO1s/ZjaIo+Ff2ZvwPA/Dyk/k6QoicM+T+mr5qe9l2lyxZwsyZM4mKiiIgIIC5c+fSqFEjAPr06UNYWBiHDx/OPv/IkSMMHz6ca9eu4eXlxejRo7MDEkBYWBh+fn7PtNO4cePs66SmpjJx4kSCgoKIjY3Fy8uLd999l0mTJmFpqZ+nQiTwCFEAosLiGNJiKo+S0mn5bj1GLOht9KFAk6nl0PYLbF19LHtSPYBfeU/avfsGzTrVwNbeWo8VGgZFUbh7I5JTB65xeOdFHtyNy37Nxs6KOs0r0rhdVWo2Lm+UozlPJMWlMH3A91w8ehOA9n0aM+Drd7CURS6EELlkyP01Yws8IovRBJ6OHTty8eJFYmNjKVKkCC1atGDGjBl4eXnl+BryzSL06dzv15jUYwE6nUKf8Z3pMbydvkvKE08ezdqz4RRHdl5ErdIAWZ35N5pXpH6bygQ2LPdaLXKQqdZw5cxdTh28zumD154aybGytqBOs4o0ap8VcgrDqncXj95k1sc/kBCdhLWdFUO/fZ+mXevouywhhJEy5P6aBB7jZDSBZ+7cudStWxdPT08iIiL4/PPPAf5186TnkW8WoW87fjjM4lHrABi7oj+Nu9TSc0V5KzU5nYNB59m9/hT378RmH7eysaBW4wrUb1OZ2k3KF7qRH0VRCA+J5cqZO1w+dYfzx/4k/VFG9utW1hbUaFCWuq0CqN8qoND8+TPVGtZO386mhb+hKAreZTyYsHogJcvl/BdRQgjxT4bcX5PAY5yMJvD80/bt2+ncuTMqlSrHK0fIN4swBMvHbyRo+UEsrMyZEfQZFWv767ukPKcoCjeC7/HH3isc/+0KsREPs1+zsDSnUk1fAmqVIqCmH+Wq+Rjd6I9Wo+Xe7RiunL3LldN3uXr2LsmJaU+dU8TNnjrNKlKneSWq1y9TKEZy/i7iTgzTB3zP7Yv3AGj7QUMGfPUO1nYFt/O4EKJwMuT+mgQe42SUgScxMZFBgwYRERHB8ePH//U8lUqFSqXK/jwlJQVvb2/5ZhF6pdXq+Kr3Uk7tvYS9sy2zd4zEt0JxfZeVbxRFIeRaRHb4iQiNe+p1cwszygSUoFItP8pX9aFkGXc8fVwxMzeM+SyP01SE3ori7vVI7lyP4M6NSMJuRZOp1jx1npW1BeWrl6Ry7VLUaFCWclW9C+USzIqisH/DSZaMWU9Gmgp7Z1uGze0lq7AJIfKMIXfuJfAYJ6MKPKNHj2bRokWkp6fzxhtvsHPnzhduhDRlyhS++OKLZ47LN4vQt4w0FWO7zuXG2bu4uDsxZ/doPEq66busfKcoCvfvxHLlTNaoyJUzoSTEJD9znrmFGSX8iuJT2h2f0sUoXqoYrsUccS3miEsxxzzd+yfjsZqUh2kkRCcTdT+R6PsJRN9PJCo86+OEmBSe92PSxs6KijVKElCrFJXrlKJsZW8sLAv3Sv+pD9NYNPJnjmw9B0DlemUZtbQvRYsb56pyQgjDZMidewk8xkmvgeffAsnfnT17lpo1awIQHx9PYmIi9+7d44svvsDJyYmdO3f+62pXMsIjDFnqwzRGdpxF2I1IPP2KMmv757h5GtcePa9KURRiHjzk6rm7XD0Tyt2bkYSHxKB6nPnCr7O1t8bVPSv82NhaYmVjiZW1RdZ7GwusrCzQ6XRkZmrRqLVoMjVoMrVkqjWkJj8mOfERSQlZb//VFoCruxP+Fb0oVSHrzb+iFx7eLoVyBOffnP7tMvOGr+FhbAqmZqZ8MKYj3T5tg5nZ63MPhBAFw5A79xJ4jJNeA098fDzx8fEvPMfX1xdr62cn+D548ABvb29OnDhB3bp1c9SefLMIQ5MQlcRnb84k+l48xf3dmbX9c1zcnfRdll7pdDriIpO4FxJDeEgM4SGxRN2LJzE2lYTY5BwFlNwytzCjiJsDHt4uePi44unjiqe3Cx7eWR87udjleZvGIj01g+8m/sLen7IeH/Yp68lni/pQrsaz+zAIIUReMOT+mgQe46TX5y/c3Nxwc3u5x3ie5LS/j+AIYWxcPZ2ZHjSCUR1nE3EnhjFd5jBz22c4F319f5iZmpriXsIF9xIu1G5S4anXFEUh/ZGKxNgU4mOSeRiXiupxJqoM9VPvMzLUmJmZYWFhhrmFGRaW5phbmGFuaYa9gw3OrvY4udrj5GKHk4s9tvZWRr8vUn64euo2sz9ZRfS9eExMTOgysAV9xneWvXWEEEIYFaOYw3PmzBnOnDlDgwYNKFKkCHfv3mXSpElERUVx7do1rKxytiqQpGNhqCJDYxnV6VviIx/iW8GLGVs/w8nVQd9lideUOiOTtTO2s3nRPhRFoVgJFz5b9CFVG5TTd2lCiNeAIffXZITHOBnFw9c2Njb8+uuvNG/enHLlytG3b18CAgI4cuRIjsOOEIbMy68YM4JG4OLuRNiNSEZ3/paEqCR9lyVeQxeOXGdQoy+y99Zp+W49lh6dJGFHCCGE0TKKEZ68IulYGLr7t6MZ3flbEmOScfdxZdrm4XiVKqbvssRrIDEmmRWTNnFoyxkAXNydGDyrJ/XaVddzZUKI140h99dkhMc4GcUIjxCvC+8yHszZPRovv2LEhCcwov0Mbl+6p++yRCGm0+nY/eNR+tedxKEtZzAxMaFj/2asOPmFhB0hhBCFggQeIQyMR0k3vt01Cv/K3iTFpTKy42zOHbyq77JEIZQ1ojiHBZ/9RFrKY0pX8WH+vrF8PK0Hdo62+i5PCCGEyBMSeIQwQEWKOTJz22dUa1SejDQVk3ou4refj+u7LFFIpKU+ZsXkzQxsOIUrJ/7EytaSj77qxvz94yhb3Vff5QkhhBB5SgKPEAbKztGWrzZ8SrNuddBpdcwduoa107ej0+n0XZowUjqdjgMbT/K/OhPZsngfWo2OWi0CWH5sCm8NaimbiAohhCiU9LoPjxDixSwszRm5pC/FSriwYe4efp69k5Ar4Yxc0hd7J3nkSOTc7Yv3WDJ2PTfO3gWyVgYcMPUd6rSqoufKhBBCiPwlgUcIA2diYkKf8V3w8ivGwpE/c/q3ywxpMZWJqwZSKsBb3+UJAxcXkcjamTvYv+4EiqJgbWdFz8/a03lAcyytZANRIYQQhZ8EHiGMRKue9fGrVIKvP1xGVGgcw9tOZ8js92nRva6+SxMGKPVhGhvm7mb7ykNkqjQANOtWh36T3sbV01m/xQkhhBAFSAKPEEakTNWSLDo4gZmDVnL2wFVmf7KKqydvM2haD6xsLPVdnjAAmWoNO1YeYt23u3iUlA5A5Xpl+XBiFyrW8tdzdUIIIUTBk8AjhJFxKGLHF+sGs/7b3fw0cwd7fzrOreAwRi7+UB5xe43pdDr+2BnMD1/9SlRoHAC+FYvzv8lvE9isEiYmJnquUAghhNAPCTxCGCFTU1PeG/kmFev4M2PA94Ree8CQFlPpMbwdPYa3w8JS/mm/Lp4EnXXf7iL02gMga1nz3uM60/LderLymhBC5IOMdDWW5uoCbU+8PBNFURR9F1FQUlJScHJyIjk5GUdHR32XI0SeSIxJZtGodZzYFQxk/VZ/xPzesp9KIafV6ji+/Tzrvt3FvZuRANjaW9NlYAu6Dm6Fjb21nisUQoiXY8j9tSe1tfAbgrmpVYG1q9GpOBC60CDviTGQXwMLYeRc3J2YuHogx7adZ/HodYRdj2BY62l0Hdya90d1wNJaVuIqTLQaLUe3nmP9nN2E/xkFgJ2jDZ0/ak7ngc1xcLbTc4VCCCGEYZERHiEKkaT4VJaN28jhX88AUKK0O5/M7En1RhX0XJl4VWkp6exZc5zt3/9O7INEAOydbOk8oDmdBzSXfZmEEIWGIffXntQWExVXoLWlpKTg7lnUIO+JMZDAI0QhdHL3RRZ8/hMPY1MAqNeuGv+b0hWvUsX0XJnIrYexKQQtP8DOHw6TnpoBgJOrPZ0+ak6n/k2xc5SgI4QoXAy5v6av2gz5nhgDeaRNiEKobrtqBNQrw9oZO9j5w2FO7L7I2QNX6fRRM979rD12Djb6LlH8h4g7MQQtP8i+dX+gzsgEwKesJ10GtaBZ1zqyDLkQQgiRQzLCI0Qhd+9WJN9N3MT5368B4FzUgd7jOtOqZ31ZwcvAaDVaTu+7zM4fDnPh8I3s4+Vq+NJ9WFveaFMVU1P5OxNCFG6G3F+TER7jJIFHiNeAoiic2X+F7yZuIuJODJA1v6fr4NY061YHSytZ2ECfEqKT2PvTcfasOUZ85EMATExMqNm8El0/aUWVBuVkHx0hxGvDkPtrEniMkwQeIV4jmWoNO384zM+zd/IoKR0AVw9nugxsQbvejbB1kKWMC4rqsZoz+69waPNpTu+7jFajA7Lm57R+vwHtPmiER0k3PVcphBAFz5D7axJ4jJMEHiFeQ+mpGexZe4ygpfuJj0oCslb8erNfEzr9rxlFism/j/yg1eq4dOwmh7ac4Y8dF0h/lJH9WsU6/nT4sAn1O9SQETchxGvNkPtrEniMkwQeIV5jmWoNhzafZtPC37h/OxoAM3NT6revQfs+jeRRqjygKAohl8M5tu08v286lR0wAYqVcKHJ27Vp1rUOvhWK669IIYQwIIbcX5PAY5wk8Agh0Ol0nNp7iU0Lf+PG2bvZx0uUdqd9n8a06FFXNrTMBUVRuHPlPke3nePY9vNEhcZlv+ZQxI5GnWrStGttKtb2l0UIhBDiHwy5vyaBxzhJ4BFCPOXOlfvsWn2E3zefJiNNBYCltQUNOtSgYcdAAptWwtJaHrn6p0y1hhtn73Du4DWO7Xg65FjZWFCrRWUad6lFndZV5JE1IYR4AUPur0ngMU4SeIQQz5WW+pjDm8+wc/URQq89yD5uY2dF7ZaVqf9mDWo2D3itFzqIDI3l/KHrnP/9GpeO3eTxXwERskJi7ZaVadgxkNotK2Nj//reJyGEyA1D7q9J4DFOEniEEC+kKAo3zt3lSNBZ/tgZnL1sMoCFlTk1GlekWqPyBNQtQ6kA70K7t49WqyP8ViQ3zt7l+tk7XDsd8tQoDmStsFajSUXqtK5CnVZVJOQIIcRLMOT+mgQe4ySBRwiRY4qi8GdwGH/sDOb4jgtEhsY+9bqdow2V6pSmcr2yVKlfFr9KJYzy8S2dTkdMeAJh1yMIuRLOjbN3uHk+lPTUjKfOMzM3pWItfwKbVSKwaSX8q3jLnBwhhHhFhtxfk8BjnCTwCCFeiqIo3LsZydn9V7h84k+unQ55biDwLutJ6So+lK7iQ5mqJSlVqYRBjXykpaQTcSeWsJuRhFwOJ+TSPUKvPXjq8bQnrO2sKF/Dj/K1SlGhZikC6pbBzsFGD1ULIUThZcj9NQk8xkkCjxAiT2g1Wu5efcDlE39y5a8AlPow7ZnzTExMKFrCBc+SbniULIqnrxseJd3w9C2Kq6czjkXs82xRBK1WR2riIx7GpfAwNustOjyeqNA4Iu7GEHk3luSER8/9WgtLc7zLeuBXsQTla5aiYi1/fCt4YWZulie1CSGEeD5D7q9J4DFOEniEEPlCURTiIx9y58p9bl+6R8jlcO5cDn9qH5p/Y2VriYOzHY4udjg422HnaIOpuSnm5uaYmZtmvZmZgQlkqjRkPFahfpyJ6rEa1WM1GekqkhMekRyfik733z/iihRzpERpj/8fharsTQn/YphbmOfBnRBCCJEbhtxfk8BjnOR/cyFEvjAxMaFocReKFnfhjTZVs48nxaUQGRpHVFgc0ffiiboXR3RYPFFhcTyMS0Gn1aFKV6NKVz+1QMKrcHK1x7moI0WKOlK0hAvFSxXDy68YXn+9f51XmhNCCCEKOwk8QogC5VzUEeeijlSs7f/MazqdjsePMkhJTCP1YRopD7Pep6c+RqvVodPo0Gq0aLU6NJlaFJ2CpZU5VraWWNn89WZtiZWtJY4u9hQp6oiTm72M1AghhBCvMekFCCEMhqmpKXaOttg52uLpW1Tf5QghhBCiEJD1U4UQQgghhBCFlgQeIYQQQgghRKElgUcIIYQQQghRaEngEUIIIYQQQhRaEniEEEIIIYQQhZYEHiGEEEIIIUShJYFHCCGEEEIIUWjJPjxCCCGEEELkQkaaCkszVYG2J16eBB4hhBBCCCFyoWelkZibWhZYexqdusDaKozkkTYhhBBCCCFEoSUjPEIIIYQQQuTCumuzcHR0LLD2UlJScPf6scDaK2wk8AghhBBCCJEL1nZWWNtZFVh7am3BtVUYySNtQgghhBBCiEJLAo8QQgghhBCi0JLAI4QQQgghhCi0JPAIIYQQQgghCi0JPEIIIYQQQohCSwKPEEIIIYQQotCSwCOEEEIIIYQotCTwCCGEEEIIIQotCTxCCCGEEEKIQksCjxBCCCGEEKLQksAjhBBCCCGEKLQk8AghhBBCCCEKLQk8QgghhBBCiEJLAo8QQgghhBCi0JLAI4QQQgghhCi0JPAIIYQQQgghCi0JPEIIIYQQQohCSwKPEEIIIYQQotCSwCOEEEIIIYQotCTwCCGEEEIIIQotCTxCCCGEEEKIQksCjxBCCCGEEKLQksAjhBBCCCGEKLSMLvCoVCqqVauGiYkJFy9e1Hc5QgghhBBCGKQlS5bg5+eHtbU1gYGBHDt27IXnHzlyhMDAQKytrSlVqhTLli175pwtW7ZQsWJFrKysqFixIkFBQa/cbn4zusAzatQovLy89F2GEEIIIYQQBmvjxo0MGzaM8ePHExwcTMOGDWnbti3h4eHPPT80NJR27drRsGFDgoODGTduHJ9++ilbtmzJPufkyZN0796dXr16cenSJXr16sU777zD6dOnX7rdgmCiKIqit9Zzac+ePYwYMYItW7ZQqVIlgoODqVatWo6/PiUlBScnJ5KTk3F0dMy/QoUQQgghxEsx5P7ak9qiI2MKtLaUlBQ8vNxzdU/q1KlDjRo1WLp0afaxChUq0LlzZ6ZNm/bM+aNHj2b79u3cuHEj+9jAgQO5dOkSJ0+eBKB79+6kpKSwZ8+e7HPatGlDkSJFWL9+/Uu1WxDM9dLqS4iJiaF///5s3boVW1vbHH2NSqVCpVJlf56cnAxkfdMIIYQQQgjD86SfZsi/k+/q9SHmWBRYexoygWf7sFZWVlhZWT1zvlqt5vz584wZM+ap461ateLEiRPPbePkyZO0atXqqWOtW7dm5cqVZGZmYmFhwcmTJxk+fPgz58ybN++l2y0IRhF4FEWhT58+DBw4kJo1axIWFpajr5s2bRpffPHFM8e9vb3zuEIhhBBCCJGXUlNTcXJy0ncZT7G0tMQSa46zu8Dbtre3f6YPO3nyZKZMmfLMufHx8Wi1Wtzd3Z867u7uTnR09HOvHx0d/dzzNRoN8fHxeHp6/us5T675Mu0WBL0GnilTpjw3kPzd2bNnOXHiBCkpKYwdOzZX1x87diwjRozI/lyn05GYmIiFhQU+Pj7cv3/f4IZKDVVKSgre3t5yz3JB7lnuyT3LPblnuSf3LPfknuWe3LPce3LPwsPDMTExMcg529bW1kTHR6FWqwu+bVsrTExMnjr2vNGdv/vn+YqiPHPsv87/5/GcXDO37eY3vQaewYMH06NHjxee4+vry9dff82pU6ee+UutWbMm7733Hj/++ONzv/Z5w3zOzs7Zw4GOjo7yQyiX5J7lntyz3JN7lntyz3JP7lnuyT3LPblnuefk5GTQ96yIq7O+S/hPbm5umJmZPTOqEhsb+8zoyxMeHh7PPd/c3BxXV9cXnvPkmi/TbkHQa+Bxc3PDzc3tP89bsGABX3/9dfbnkZGRtG7dmo0bN1KnTp38LFEIIYQQQgijYmlpSWBgIPv376dLly7Zx/fv30+nTp2e+zV169Zlx44dTx3bt28fNWvWxMLCIvuc/fv3PzWPZ9++fdSrV++l2y0IRjGHx8fH56nP7e3tAfD396dEiRL6KEkIIYQQQgiDNWLECHr16kXNmjWpW7cu3333HeHh4QwcOBDImvoRERHBmjVrgKwV2RYtWsSIESPo378/J0+eZOXKldmrrwEMHTqURo0aMWPGDDp16sS2bds4cOAAx48fz3G7+mAUgSevWVlZMXny5P987lH8P7lnuSf3LPfknuWe3LPck3uWe3LPck/uWe7JPctb3bt3JyEhgS+//JKoqCgCAgLYvXs3JUuWBCAqKuqpvXH8/PzYvXs3w4cPZ/HixXh5ebFgwQLefvvt7HPq1avHhg0bmDBhAhMnTsTf3/+ZJ67+q119MKp9eIQQQgghhBAiN0z1XYAQQgghhBBC5BcJPEIIIYQQQohCSwKPEEIIIYQQotCSwCOEEEIIIYQotCTw/EWlUlGtWjVMTEy4ePGivssxaB07dsTHxwdra2s8PT3p1asXkZGR+i7LYIWFhdGvXz/8/PywsbHB39+fyZMn62WXZmMydepU6tWrh62tLc7OzvouxyAtWbIEPz8/rK2tCQwM5NixY/ouyaAdPXqUDh064OXlhYmJCVu3btV3SQZt2rRp1KpVCwcHB4oVK0bnzp25deuWvssyaEuXLqVKlSrZm43WrVuXPXv26LssozJt2jRMTEwYNmyYvksRhYgEnr+MGjUKLy8vfZdhFJo2bcovv/zCrVu32LJlC3fu3KFr1676Lstg3bx5E51Ox/Lly7l27Rpz585l2bJljBs3Tt+lGTS1Wk23bt0YNGiQvksxSBs3bmTYsGGMHz+e4OBgGjZsSNu2bZ9aYlQ8LS0tjapVq7Jo0SJ9l2IUjhw5wieffMKpU6fYv38/Go2GVq1akZaWpu/SDFaJEiWYPn06586d49y5czRr1oxOnTpx7do1fZdmFM6ePct3331HlSpV9F2KKGwUoezevVspX768cu3aNQVQgoOD9V2SUdm2bZtiYmKiqNVqfZdiNGbOnKn4+fnpuwyjsGrVKsXJyUnfZRic2rVrKwMHDnzqWPny5ZUxY8boqSLjAihBQUH6LsOoxMbGKoBy5MgRfZdiVIoUKaJ8//33+i7D4KWmpiplypRR9u/frzRu3FgZOnSovksShchrP8ITExND//79Wbt2Lba2tvoux+gkJiby888/U69ePSwsLPRdjtFITk7GxcVF32UII6VWqzl//jytWrV66nirVq04ceKEnqoShV1ycjKA/OzKIa1Wy4YNG0hLS6Nu3br6LsfgffLJJ7Rv354WLVrouxRRCL3WgUdRFPr06cPAgQOpWbOmvssxKqNHj8bOzg5XV1fCw8PZtm2bvksyGnfu3GHhwoUMHDhQ36UIIxUfH49Wq8Xd3f2p4+7u7kRHR+upKlGYKYrCiBEjaNCgAQEBAfoux6BduXIFe3t7rKysGDhwIEFBQVSsWFHfZRm0DRs2cOHCBaZNm6bvUkQhVSgDz5QpUzAxMXnh27lz51i4cCEpKSmMHTtW3yXrXU7v2RMjR44kODiYffv2YWZmxgcffICiKHr8ExS83N4zgMjISNq0aUO3bt343//+p6fK9edl7pn4dyYmJk99rijKM8eEyAuDBw/m8uXLrF+/Xt+lGLxy5cpx8eJFTp06xaBBg+jduzfXr1/Xd1kG6/79+wwdOpSffvoJa2trfZcjCikTpRD2UuPj44mPj3/hOb6+vvTo0YMdO3Y81UHQarWYmZnx3nvv8eOPP+Z3qQYjp/fseT+MHjx4gLe3NydOnHithu1ze88iIyNp2rQpderUYfXq1ZiaFsrfN7zQy3yfrV69mmHDhpGUlJTP1RkPtVqNra0tmzZtokuXLtnHhw4dysWLFzly5IgeqzMOJiYmBAUF0blzZ32XYvCGDBnC1q1bOXr0KH5+fvoux+i0aNECf39/li9fru9SDNLWrVvp0qULZmZm2ce0Wi0mJiaYmpqiUqmeek2Il2Gu7wLyg5ubG25ubv953oIFC/j666+zP4+MjKR169Zs3LiROnXq5GeJBien9+x5nmRmlUqVlyUZvNzcs4iICJo2bUpgYCCrVq16LcMOvNr3mfh/lpaWBAYGsn///qcCz/79++nUqZMeKxOFiaIoDBkyhKCgIA4fPixh5yUpivLa/f+YG82bN+fKlStPHfvwww8pX748o0ePlrAj8kShDDw55ePj89Tn9vb2APj7+1OiRAl9lGTwzpw5w5kzZ2jQoAFFihTh7t27TJo0CX9//9dqdCc3IiMjadKkCT4+PsyePZu4uLjs1zw8PPRYmWELDw8nMTGR8PBwtFpt9v5YpUuXzv63+jobMWIEvXr1ombNmtStW5fvvvuO8PBwmRv2Ao8ePSIkJCT789DQUC5evIiLi8sz/x+IrEnk69atY9u2bTg4OGTPD3NycsLGxkbP1RmmcePG0bZtW7y9vUlNTWXDhg0cPnyYvXv36rs0g+Xg4PDMvLAnc4RlvpjIK6914BG5Z2Njw6+//srkyZNJS0vD09OTNm3asGHDBqysrPRdnkHat28fISEhhISEPBOkC+ETpXlm0qRJTz1WWr16dQAOHTpEkyZN9FSV4ejevTsJCQl8+eWXREVFERAQwO7duylZsqS+SzNY586do2nTptmfjxgxAoDevXuzevVqPVVluJYuXQrwzL+3VatW0adPn4IvyAjExMTQq1cvoqKicHJyokqVKuzdu5eWLVvquzQhXmuFcg6PEEIIIYQQQkAhXaVNCCGEEEIIIUACjxBCCCGEEKIQk8AjhBBCCCGEKLQk8AghhBBCCCEKLQk8QgghhBBCiEJLAo8QQgghhBCi0JLAI4QQQgghhCi0JPAIIYQQQgghCi0JPEIIIYQQQohCSwKPEEIIIYQQotCSwCOEEEIIIYQotCTwCCGEkYmLi8PDw4Nvvvkm+9jp06extLRk3759eqxMCCGEMDwmiqIo+i5CCCFE7uzevZvOnTtz4sQJypcvT/Xq1Wnfvj3z5s3Td2lCCCGEQZHAI4QQRuqTTz7hwIED1KpVi0uXLnH27Fmsra31XZYQQghhUCTwCCGEkXr8+DEBAQHcv3+fc+fOUaVKFX2XJIQQQhgcmcMjhBBG6u7du0RGRqLT6bh3756+yxFCCCEMkozwCCGEEVKr1dSuXZtq1apRvnx55syZw5UrV3B3d9d3aUIIIYRBkcAjhBBGaOTIkWzevJlLly5hb29P06ZNcXBwYOfOnfouTQghhDAo8kibEEIYmcOHDzNv3jzWrl2Lo6MjpqamrF27luPHj7N06VJ90i7/XAAAAI9JREFUlyeEEEIYFBnhEUIIIYQQQhRaMsIjhBBCCCGEKLQk8AghhBBCCCEKLQk8QgghhBBCiEJLAo8QQgghhBCi0JLAI4QQQgghhCi0JPAIIYQQQgghCi0JPEIIIYQQQohCSwKPEEIIIYQQotCSwCOEEEIIIYQotCTwCCGEEEIIIQotCTxCCCGEEEKIQuv/ACwT0paaevloAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Define the parameters of the Gaussian\n", + "mean = jnp.array([0.0, 0.0])\n", + "cov = jnp.array([[1.0, 0.5], [0.5, 2.0]])\n", + "\n", + "# Define the log-density function\n", + "def logdensity_fn(position):\n", + " return stats.multivariate_normal.logpdf(position, mean, cov)\n", + "\n", + "# Visualize the target distribution\n", + "def plot_gaussian():\n", + " x = np.linspace(-4, 4, 100)\n", + " y = np.linspace(-4, 4, 100)\n", + " X, Y = np.meshgrid(x, y)\n", + " Z = np.zeros((100, 100))\n", + " for i in range(100):\n", + " for j in range(100):\n", + " Z[i, j] = np.exp(logdensity_fn(np.array([X[i, j], Y[i, j]])))\n", + " \n", + " plt.figure(figsize=(10, 8))\n", + " plt.contour(X, Y, Z, levels=20)\n", + " plt.colorbar(label='Density')\n", + " plt.xlabel('x')\n", + " plt.ylabel('y')\n", + " plt.title('2D Gaussian Target Distribution')\n", + " plt.axis('equal')\n", + " plt.show()\n", + "\n", + "plot_gaussian()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Set Up the Velocity Verlet Integrator\n", + "\n", + "Now, let's set up the velocity verlet integrator. We need to:\n", + "1. Define a kinetic energy function\n", + "2. Create an integrator state\n", + "3. Run the integrator for a few steps" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# Define the inverse mass matrix (for the kinetic energy)\n", + "inverse_mass_matrix = jnp.eye(2) # Identity matrix for simplicity\n", + "\n", + "# Create a metric object\n", + "metric = metrics.default_metric(inverse_mass_matrix)\n", + "\n", + "# Get the kinetic energy function from the metric\n", + "kinetic_energy_fn = metric.kinetic_energy\n", + "\n", + "# Create the velocity verlet integrator\n", + "integrator = integrators.velocity_verlet(logdensity_fn, kinetic_energy_fn)\n", + "\n", + "# Set the initial position and momentum\n", + "initial_position = jnp.array([2.0, 2.0])\n", + "initial_momentum = jnp.array([0.5, -0.3])\n", + "\n", + "# Create the initial integrator state\n", + "initial_state = integrators.new_integrator_state(logdensity_fn, initial_position, initial_momentum)\n", + "\n", + "# Set the step size and number of steps\n", + "step_size = 0.1\n", + "num_steps = 50" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "IntegratorState(position=Array([2.0414286, 1.9671428], dtype=float32), momentum=Array([ 0.3257347 , -0.35561225], dtype=float32), logdensity=Array(-4.457322, dtype=float32), logdensity_grad=Array([-1.7710204 , -0.54081637], dtype=float32))" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "integrator(initial_state, step_size)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Run the Integrator and Visualize the Trajectory\n", + "\n", + "Now, let's run the integrator for a few steps and visualize the trajectory:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "ename": "AttributeError", + "evalue": "'jaxlib.xla_extension.ArrayImpl' object has no attribute 'position'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[5], line 14\u001b[0m\n\u001b[1;32m 11\u001b[0m states \u001b[38;5;241m=\u001b[39m run_integrator(initial_state, integrator, step_size, num_steps)\n\u001b[1;32m 13\u001b[0m \u001b[38;5;66;03m# Extract positions and momenta\u001b[39;00m\n\u001b[0;32m---> 14\u001b[0m positions \u001b[38;5;241m=\u001b[39m jnp\u001b[38;5;241m.\u001b[39marray(\u001b[43m[\u001b[49m\u001b[43mstate\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mposition\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mstate\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mstates\u001b[49m\u001b[43m]\u001b[49m)\n\u001b[1;32m 15\u001b[0m momenta \u001b[38;5;241m=\u001b[39m jnp\u001b[38;5;241m.\u001b[39marray([state\u001b[38;5;241m.\u001b[39mmomentum \u001b[38;5;28;01mfor\u001b[39;00m state \u001b[38;5;129;01min\u001b[39;00m states])\n\u001b[1;32m 17\u001b[0m \u001b[38;5;66;03m# Visualize the trajectory\u001b[39;00m\n", + "Cell \u001b[0;32mIn[5], line 14\u001b[0m, in \u001b[0;36m\u001b[0;34m(.0)\u001b[0m\n\u001b[1;32m 11\u001b[0m states \u001b[38;5;241m=\u001b[39m run_integrator(initial_state, integrator, step_size, num_steps)\n\u001b[1;32m 13\u001b[0m \u001b[38;5;66;03m# Extract positions and momenta\u001b[39;00m\n\u001b[0;32m---> 14\u001b[0m positions \u001b[38;5;241m=\u001b[39m jnp\u001b[38;5;241m.\u001b[39marray([\u001b[43mstate\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mposition\u001b[49m \u001b[38;5;28;01mfor\u001b[39;00m state \u001b[38;5;129;01min\u001b[39;00m states])\n\u001b[1;32m 15\u001b[0m momenta \u001b[38;5;241m=\u001b[39m jnp\u001b[38;5;241m.\u001b[39marray([state\u001b[38;5;241m.\u001b[39mmomentum \u001b[38;5;28;01mfor\u001b[39;00m state \u001b[38;5;129;01min\u001b[39;00m states])\n\u001b[1;32m 17\u001b[0m \u001b[38;5;66;03m# Visualize the trajectory\u001b[39;00m\n", + "\u001b[0;31mAttributeError\u001b[0m: 'jaxlib.xla_extension.ArrayImpl' object has no attribute 'position'" + ] + } + ], + "source": [ + "# Function to run the integrator for multiple steps\n", + "def run_integrator(initial_state, integrator, step_size, num_steps):\n", + " def one_step(state, _):\n", + " new_state = integrator(state, step_size)\n", + " return new_state, new_state\n", + " \n", + " _, states = jax.lax.scan(one_step, initial_state, None, length=num_steps)\n", + " return states\n", + "\n", + "# Run the integrator\n", + "states = run_integrator(initial_state, integrator, step_size, num_steps)\n", + "\n", + "# Extract positions and momenta\n", + "positions = jnp.array([state.position for state in states])\n", + "momenta = jnp.array([state.momentum for state in states])\n", + "\n", + "# Visualize the trajectory\n", + "def plot_trajectory(positions, momenta):\n", + " x = np.linspace(-4, 4, 100)\n", + " y = np.linspace(-4, 4, 100)\n", + " X, Y = np.meshgrid(x, y)\n", + " Z = np.zeros((100, 100))\n", + " for i in range(100):\n", + " for j in range(100):\n", + " Z[i, j] = np.exp(logdensity_fn(np.array([X[i, j], Y[i, j]])))\n", + " \n", + " plt.figure(figsize=(12, 10))\n", + " \n", + " # Plot the target distribution\n", + " plt.subplot(2, 2, 1)\n", + " plt.contour(X, Y, Z, levels=20)\n", + " plt.colorbar(label='Density')\n", + " plt.plot(positions[:, 0], positions[:, 1], 'r-', label='Trajectory')\n", + " plt.plot(positions[0, 0], positions[0, 1], 'go', label='Start')\n", + " plt.plot(positions[-1, 0], positions[-1, 1], 'bo', label='End')\n", + " plt.xlabel('x')\n", + " plt.ylabel('y')\n", + " plt.title('Position Trajectory')\n", + " plt.legend()\n", + " plt.axis('equal')\n", + " \n", + " # Plot the momentum trajectory\n", + " plt.subplot(2, 2, 2)\n", + " plt.plot(momenta[:, 0], momenta[:, 1], 'b-', label='Trajectory')\n", + " plt.plot(momenta[0, 0], momenta[0, 1], 'go', label='Start')\n", + " plt.plot(momenta[-1, 0], momenta[-1, 1], 'ro', label='End')\n", + " plt.xlabel('p_x')\n", + " plt.ylabel('p_y')\n", + " plt.title('Momentum Trajectory')\n", + " plt.legend()\n", + " plt.axis('equal')\n", + " \n", + " # Plot position vs time\n", + " plt.subplot(2, 2, 3)\n", + " time = np.arange(num_steps) * step_size\n", + " plt.plot(time, positions[:, 0], 'r-', label='x')\n", + " plt.plot(time, positions[:, 1], 'b-', label='y')\n", + " plt.xlabel('Time')\n", + " plt.ylabel('Position')\n", + " plt.title('Position vs Time')\n", + " plt.legend()\n", + " \n", + " # Plot momentum vs time\n", + " plt.subplot(2, 2, 4)\n", + " plt.plot(time, momenta[:, 0], 'r-', label='p_x')\n", + " plt.plot(time, momenta[:, 1], 'b-', label='p_y')\n", + " plt.xlabel('Time')\n", + " plt.ylabel('Momentum')\n", + " plt.title('Momentum vs Time')\n", + " plt.legend()\n", + " \n", + " plt.tight_layout()\n", + " plt.show()\n", + "\n", + "plot_trajectory(positions, momenta)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Energy Conservation\n", + "\n", + "One of the key properties of Hamiltonian dynamics is energy conservation. Let's check if our integrator preserves energy:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Calculate the total energy (potential + kinetic) at each step\n", + "def calculate_energy(states):\n", + " # Potential energy is the negative log-density\n", + " potential_energy = -jnp.array([state.logdensity for state in states])\n", + " \n", + " # Kinetic energy\n", + " kinetic_energy = jnp.array([kinetic_energy_fn(state.momentum) for state in states])\n", + " \n", + " # Total energy\n", + " total_energy = potential_energy + kinetic_energy\n", + " \n", + " return potential_energy, kinetic_energy, total_energy\n", + "\n", + "potential_energy, kinetic_energy, total_energy = calculate_energy(states)\n", + "\n", + "# Plot the energy components\n", + "plt.figure(figsize=(12, 6))\n", + "time = np.arange(num_steps) * step_size\n", + "plt.plot(time, potential_energy, 'r-', label='Potential Energy')\n", + "plt.plot(time, kinetic_energy, 'b-', label='Kinetic Energy')\n", + "plt.plot(time, total_energy, 'g-', label='Total Energy')\n", + "plt.xlabel('Time')\n", + "plt.ylabel('Energy')\n", + "plt.title('Energy Conservation')\n", + "plt.legend()\n", + "plt.grid(True)\n", + "plt.show()\n", + "\n", + "# Calculate the relative energy error\n", + "initial_total_energy = total_energy[0]\n", + "relative_energy_error = jnp.abs(total_energy - initial_total_energy) / jnp.abs(initial_total_energy)\n", + "max_relative_error = jnp.max(relative_energy_error)\n", + "print(f\"Maximum relative energy error: {max_relative_error:.6f}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Time Reversibility\n", + "\n", + "Another important property of Hamiltonian dynamics is time reversibility. Let's check if our integrator is time-reversible by running it forward and then backward:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Function to run the integrator backward (by negating the step size)\n", + "def run_integrator_backward(final_state, integrator, step_size, num_steps):\n", + " def one_step(state, _):\n", + " new_state = integrator(state, -step_size) # Negative step size for backward integration\n", + " return new_state, new_state\n", + " \n", + " _, states = jax.lax.scan(one_step, final_state, None, length=num_steps)\n", + " return states\n", + "\n", + "# Run the integrator forward\n", + "forward_states = run_integrator(initial_state, integrator, step_size, num_steps)\n", + "final_state = forward_states[-1]\n", + "\n", + "# Run the integrator backward\n", + "backward_states = run_integrator_backward(final_state, integrator, step_size, num_steps)\n", + "reversed_state = backward_states[-1]\n", + "\n", + "# Check if we've returned to the initial state\n", + "position_error = jnp.linalg.norm(initial_state.position - reversed_state.position)\n", + "momentum_error = jnp.linalg.norm(initial_state.momentum - reversed_state.momentum)\n", + "\n", + "print(f\"Position error: {position_error:.10f}\")\n", + "print(f\"Momentum error: {momentum_error:.10f}\")\n", + "\n", + "# Visualize the forward and backward trajectories\n", + "def plot_reversibility(forward_states, backward_states):\n", + " forward_positions = jnp.array([state.position for state in forward_states])\n", + " backward_positions = jnp.array([state.position for state in backward_states])\n", + " \n", + " x = np.linspace(-4, 4, 100)\n", + " y = np.linspace(-4, 4, 100)\n", + " X, Y = np.meshgrid(x, y)\n", + " Z = np.zeros((100, 100))\n", + " for i in range(100):\n", + " for j in range(100):\n", + " Z[i, j] = np.exp(logdensity_fn(np.array([X[i, j], Y[i, j]])))\n", + " \n", + " plt.figure(figsize=(10, 8))\n", + " plt.contour(X, Y, Z, levels=20)\n", + " plt.colorbar(label='Density')\n", + " plt.plot(forward_positions[:, 0], forward_positions[:, 1], 'r-', label='Forward')\n", + " plt.plot(backward_positions[:, 0], backward_positions[:, 1], 'b--', label='Backward')\n", + " plt.plot(forward_positions[0, 0], forward_positions[0, 1], 'go', label='Start')\n", + " plt.plot(forward_positions[-1, 0], forward_positions[-1, 1], 'bo', label='End')\n", + " plt.plot(backward_positions[-1, 0], backward_positions[-1, 1], 'ro', label='Reversed')\n", + " plt.xlabel('x')\n", + " plt.ylabel('y')\n", + " plt.title('Time Reversibility')\n", + " plt.legend()\n", + " plt.axis('equal')\n", + " plt.show()\n", + "\n", + "plot_reversibility(forward_states, backward_states)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Conclusion\n", + "\n", + "In this notebook, we've demonstrated how to use the velocity verlet integrator from Blackjax to simulate Hamiltonian dynamics for a Gaussian target distribution. We've shown that:\n", + "\n", + "1. The integrator can be used to simulate the trajectory of a particle in the potential energy landscape defined by the negative log-density of the target distribution.\n", + "2. The integrator approximately conserves energy, with small errors due to the numerical approximation.\n", + "3. The integrator is time-reversible, meaning that running it forward and then backward returns to the initial state (up to numerical errors).\n", + "\n", + "These properties make the velocity verlet integrator a good choice for Hamiltonian Monte Carlo, where we want to simulate Hamiltonian dynamics to propose new states in the Markov chain." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.9" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/velocity_verlet_gaussian_with_equivalence.ipynb b/velocity_verlet_gaussian_with_equivalence.ipynb new file mode 100644 index 000000000..d36c21f1c --- /dev/null +++ b/velocity_verlet_gaussian_with_equivalence.ipynb @@ -0,0 +1,558 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Velocity Verlet Integrator for a Gaussian Target\n", + "\n", + "This notebook demonstrates how to use the velocity verlet integrator from Blackjax to simulate Hamiltonian dynamics for a Gaussian target distribution." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "\n", + "import jax\n", + "import jax.numpy as jnp\n", + "import jax.scipy.stats as stats\n", + "\n", + "import blackjax\n", + "from blackjax.mcmc import integrators\n", + "from blackjax.mcmc import metrics\n", + "from blackjax.types import ArrayTree\n", + "\n", + "# Set random seed for reproducibility\n", + "rng_key = jax.random.key(42)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Define a Gaussian Target Distribution\n", + "\n", + "We'll use a 2D Gaussian distribution as our target. The log-density function is defined as:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Define the parameters of the Gaussian\n", + "mean = jnp.array([0.0, 0.0])\n", + "cov = jnp.array([[1.0, 0.5], [0.5, 2.0]])\n", + "\n", + "# Define the log-density function\n", + "def logdensity_fn(position):\n", + " return stats.multivariate_normal.logpdf(position, mean, cov)\n", + "\n", + "# Visualize the target distribution\n", + "def plot_gaussian():\n", + " x = np.linspace(-4, 4, 100)\n", + " y = np.linspace(-4, 4, 100)\n", + " X, Y = np.meshgrid(x, y)\n", + " Z = np.zeros((100, 100))\n", + " for i in range(100):\n", + " for j in range(100):\n", + " Z[i, j] = np.exp(logdensity_fn(np.array([X[i, j], Y[i, j]])))\n", + " \n", + " plt.figure(figsize=(10, 8))\n", + " plt.contour(X, Y, Z, levels=20)\n", + " plt.colorbar(label='Density')\n", + " plt.xlabel('x')\n", + " plt.ylabel('y')\n", + " plt.title('2D Gaussian Target Distribution')\n", + " plt.axis('equal')\n", + " plt.show()\n", + "\n", + "plot_gaussian()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Set Up the Velocity Verlet Integrator\n", + "\n", + "Now, let's set up the velocity verlet integrator. We need to:\n", + "1. Define a kinetic energy function\n", + "2. Create an integrator state\n", + "3. Run the integrator for a few steps" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Define the inverse mass matrix (for the kinetic energy)\n", + "inverse_mass_matrix = jnp.eye(2) # Identity matrix for simplicity\n", + "\n", + "# Create a metric object\n", + "metric = metrics.default_metric(inverse_mass_matrix)\n", + "\n", + "# Get the kinetic energy function from the metric\n", + "kinetic_energy_fn = metric.kinetic_energy\n", + "\n", + "# Create the velocity verlet integrator\n", + "integrator = integrators.velocity_verlet(logdensity_fn, kinetic_energy_fn)\n", + "\n", + "# Set the initial position and momentum\n", + "initial_position = jnp.array([2.0, 2.0])\n", + "initial_momentum = jnp.array([0.5, -0.3])\n", + "\n", + "# Create the initial integrator state\n", + "initial_state = integrators.new_integrator_state(logdensity_fn, initial_position, initial_momentum)\n", + "\n", + "# Set the step size and number of steps\n", + "step_size = 0.1\n", + "num_steps = 50" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Run the Integrator and Visualize the Trajectory\n", + "\n", + "Now, let's run the integrator for a few steps and visualize the trajectory:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Function to run the integrator for multiple steps\n", + "def run_integrator(initial_state, integrator, step_size, num_steps):\n", + " def one_step(state, _):\n", + " new_state = integrator(state, step_size)\n", + " return new_state, new_state\n", + " \n", + " _, states = jax.lax.scan(one_step, initial_state, None, length=num_steps)\n", + " return states\n", + "\n", + "# Run the integrator\n", + "states = run_integrator(initial_state, integrator, step_size, num_steps)\n", + "\n", + "# Extract positions and momenta\n", + "positions = jnp.array([state.position for state in states])\n", + "momenta = jnp.array([state.momentum for state in states])\n", + "\n", + "# Visualize the trajectory\n", + "def plot_trajectory(positions, momenta):\n", + " x = np.linspace(-4, 4, 100)\n", + " y = np.linspace(-4, 4, 100)\n", + " X, Y = np.meshgrid(x, y)\n", + " Z = np.zeros((100, 100))\n", + " for i in range(100):\n", + " for j in range(100):\n", + " Z[i, j] = np.exp(logdensity_fn(np.array([X[i, j], Y[i, j]])))\n", + " \n", + " plt.figure(figsize=(12, 10))\n", + " \n", + " # Plot the target distribution\n", + " plt.subplot(2, 2, 1)\n", + " plt.contour(X, Y, Z, levels=20)\n", + " plt.colorbar(label='Density')\n", + " plt.plot(positions[:, 0], positions[:, 1], 'r-', label='Trajectory')\n", + " plt.plot(positions[0, 0], positions[0, 1], 'go', label='Start')\n", + " plt.plot(positions[-1, 0], positions[-1, 1], 'bo', label='End')\n", + " plt.xlabel('x')\n", + " plt.ylabel('y')\n", + " plt.title('Position Trajectory')\n", + " plt.legend()\n", + " plt.axis('equal')\n", + " \n", + " # Plot the momentum trajectory\n", + " plt.subplot(2, 2, 2)\n", + " plt.plot(momenta[:, 0], momenta[:, 1], 'b-', label='Trajectory')\n", + " plt.plot(momenta[0, 0], momenta[0, 1], 'go', label='Start')\n", + " plt.plot(momenta[-1, 0], momenta[-1, 1], 'ro', label='End')\n", + " plt.xlabel('p_x')\n", + " plt.ylabel('p_y')\n", + " plt.title('Momentum Trajectory')\n", + " plt.legend()\n", + " plt.axis('equal')\n", + " \n", + " # Plot position vs time\n", + " plt.subplot(2, 2, 3)\n", + " time = np.arange(num_steps) * step_size\n", + " plt.plot(time, positions[:, 0], 'r-', label='x')\n", + " plt.plot(time, positions[:, 1], 'b-', label='y')\n", + " plt.xlabel('Time')\n", + " plt.ylabel('Position')\n", + " plt.title('Position vs Time')\n", + " plt.legend()\n", + " \n", + " # Plot momentum vs time\n", + " plt.subplot(2, 2, 4)\n", + " plt.plot(time, momenta[:, 0], 'r-', label='p_x')\n", + " plt.plot(time, momenta[:, 1], 'b-', label='p_y')\n", + " plt.xlabel('Time')\n", + " plt.ylabel('Momentum')\n", + " plt.title('Momentum vs Time')\n", + " plt.legend()\n", + " \n", + " plt.tight_layout()\n", + " plt.show()\n", + "\n", + "plot_trajectory(positions, momenta)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Energy Conservation\n", + "\n", + "One of the key properties of Hamiltonian dynamics is energy conservation. Let's check if our integrator preserves energy:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Calculate the total energy (potential + kinetic) at each step\n", + "def calculate_energy(states):\n", + " # Potential energy is the negative log-density\n", + " potential_energy = -jnp.array([state.logdensity for state in states])\n", + " \n", + " # Kinetic energy\n", + " kinetic_energy = jnp.array([kinetic_energy_fn(state.momentum) for state in states])\n", + " \n", + " # Total energy\n", + " total_energy = potential_energy + kinetic_energy\n", + " \n", + " return potential_energy, kinetic_energy, total_energy\n", + "\n", + "potential_energy, kinetic_energy, total_energy = calculate_energy(states)\n", + "\n", + "# Plot the energy components\n", + "plt.figure(figsize=(12, 6))\n", + "time = np.arange(num_steps) * step_size\n", + "plt.plot(time, potential_energy, 'r-', label='Potential Energy')\n", + "plt.plot(time, kinetic_energy, 'b-', label='Kinetic Energy')\n", + "plt.plot(time, total_energy, 'g-', label='Total Energy')\n", + "plt.xlabel('Time')\n", + "plt.ylabel('Energy')\n", + "plt.title('Energy Conservation')\n", + "plt.legend()\n", + "plt.grid(True)\n", + "plt.show()\n", + "\n", + "# Calculate the relative energy error\n", + "initial_total_energy = total_energy[0]\n", + "relative_energy_error = jnp.abs(total_energy - initial_total_energy) / jnp.abs(initial_total_energy)\n", + "max_relative_error = jnp.max(relative_energy_error)\n", + "print(f\"Maximum relative energy error: {max_relative_error:.6f}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Time Reversibility\n", + "\n", + "Another important property of Hamiltonian dynamics is time reversibility. Let's check if our integrator is time-reversible by running it forward and then backward:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Function to run the integrator backward (by negating the step size)\n", + "def run_integrator_backward(final_state, integrator, step_size, num_steps):\n", + " def one_step(state, _):\n", + " new_state = integrator(state, -step_size) # Negative step size for backward integration\n", + " return new_state, new_state\n", + " \n", + " _, states = jax.lax.scan(one_step, final_state, None, length=num_steps)\n", + " return states\n", + "\n", + "# Run the integrator forward\n", + "forward_states = run_integrator(initial_state, integrator, step_size, num_steps)\n", + "final_state = forward_states[-1]\n", + "\n", + "# Run the integrator backward\n", + "backward_states = run_integrator_backward(final_state, integrator, step_size, num_steps)\n", + "reversed_state = backward_states[-1]\n", + "\n", + "# Check if we've returned to the initial state\n", + "position_error = jnp.linalg.norm(initial_state.position - reversed_state.position)\n", + "momentum_error = jnp.linalg.norm(initial_state.momentum - reversed_state.momentum)\n", + "\n", + "print(f\"Position error: {position_error:.10f}\")\n", + "print(f\"Momentum error: {momentum_error:.10f}\")\n", + "\n", + "# Visualize the forward and backward trajectories\n", + "def plot_reversibility(forward_states, backward_states):\n", + " forward_positions = jnp.array([state.position for state in forward_states])\n", + " backward_positions = jnp.array([state.position for state in backward_states])\n", + " \n", + " x = np.linspace(-4, 4, 100)\n", + " y = np.linspace(-4, 4, 100)\n", + " X, Y = np.meshgrid(x, y)\n", + " Z = np.zeros((100, 100))\n", + " for i in range(100):\n", + " for j in range(100):\n", + " Z[i, j] = np.exp(logdensity_fn(np.array([X[i, j], Y[i, j]])))\n", + " \n", + " plt.figure(figsize=(10, 8))\n", + " plt.contour(X, Y, Z, levels=20)\n", + " plt.colorbar(label='Density')\n", + " plt.plot(forward_positions[:, 0], forward_positions[:, 1], 'r-', label='Forward')\n", + " plt.plot(backward_positions[:, 0], backward_positions[:, 1], 'b--', label='Backward')\n", + " plt.plot(forward_positions[0, 0], forward_positions[0, 1], 'go', label='Start')\n", + " plt.plot(forward_positions[-1, 0], forward_positions[-1, 1], 'bo', label='End')\n", + " plt.plot(backward_positions[-1, 0], backward_positions[-1, 1], 'ro', label='Reversed')\n", + " plt.xlabel('x')\n", + " plt.ylabel('y')\n", + " plt.title('Time Reversibility')\n", + " plt.legend()\n", + " plt.axis('equal')\n", + " plt.show()\n", + "\n", + "plot_reversibility(forward_states, backward_states)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Equivalence of Mass Matrix and Covariance Matrix\n", + "\n", + "Now, let's demonstrate an interesting property of Hamiltonian dynamics: using a mass matrix that is the inverse of the covariance matrix is equivalent to using a unit mass matrix on a Gaussian with unit covariance.\n", + "\n", + "This is a fundamental insight in Hamiltonian Monte Carlo, as it allows us to transform the problem into a simpler one with isotropic dynamics.\n", + "\n", + "### Mathematical Explanation\n", + "\n", + "For a Gaussian target with covariance matrix $\\Sigma$, the log-density is:\n", + "\n", + "$$\\log p(x) = -\\frac{1}{2}(x-\\mu)^T \\Sigma^{-1} (x-\\mu) + \\text{const}$$\n", + "\n", + "If we use a mass matrix $M = \\Sigma$, the Hamiltonian becomes:\n", + "\n", + "$$H(x, p) = -\\log p(x) + \\frac{1}{2}p^T M^{-1} p = \\frac{1}{2}(x-\\mu)^T \\Sigma^{-1} (x-\\mu) + \\frac{1}{2}p^T \\Sigma^{-1} p$$\n", + "\n", + "Now, let's transform the variables:\n", + "\n", + "$$x' = \\Sigma^{-1/2}(x-\\mu)$$\n", + "$$p' = \\Sigma^{1/2}p$$\n", + "\n", + "The Hamiltonian in the transformed variables becomes:\n", + "\n", + "$$H(x', p') = \\frac{1}{2}x'^T x' + \\frac{1}{2}p'^T p'$$\n", + "\n", + "This is the Hamiltonian for a standard Gaussian with unit covariance and unit mass matrix.\n", + "\n", + "Let's demonstrate this equivalence numerically:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Define a function to transform coordinates\n", + "def transform_coordinates(position, momentum, cov):\n", + " # Compute the Cholesky decomposition of the covariance matrix\n", + " L = jnp.linalg.cholesky(cov)\n", + " L_inv = jnp.linalg.inv(L)\n", + " \n", + " # Transform position and momentum\n", + " position_transformed = L_inv @ (position - mean)\n", + " momentum_transformed = L.T @ momentum\n", + " \n", + " return position_transformed, momentum_transformed\n", + "\n", + "# Define a function to inverse transform coordinates\n", + "def inverse_transform_coordinates(position_transformed, momentum_transformed, cov):\n", + " # Compute the Cholesky decomposition of the covariance matrix\n", + " L = jnp.linalg.cholesky(cov)\n", + " L_inv = jnp.linalg.inv(L)\n", + " \n", + " # Inverse transform position and momentum\n", + " position = L @ position_transformed + mean\n", + " momentum = L_inv.T @ momentum_transformed\n", + " \n", + " return position, momentum\n", + "\n", + "# Define a standard Gaussian log-density function (unit covariance)\n", + "def standard_logdensity_fn(position):\n", + " return stats.multivariate_normal.logpdf(position, jnp.zeros(2), jnp.eye(2))\n", + "\n", + "# Set up three integrators:\n", + "# 1. Original Gaussian with unit mass matrix\n", + "original_metric = metrics.default_metric(jnp.eye(2))\n", + "original_integrator = integrators.velocity_verlet(logdensity_fn, original_metric.kinetic_energy)\n", + "\n", + "# 2. Original Gaussian with mass matrix = covariance matrix\n", + "cov_mass_metric = metrics.default_metric(cov)\n", + "cov_mass_integrator = integrators.velocity_verlet(logdensity_fn, cov_mass_metric.kinetic_energy)\n", + "\n", + "# 3. Standard Gaussian (unit covariance) with unit mass matrix\n", + "standard_metric = metrics.default_metric(jnp.eye(2))\n", + "standard_integrator = integrators.velocity_verlet(standard_logdensity_fn, standard_metric.kinetic_energy)\n", + "\n", + "# Set initial conditions\n", + "initial_position = jnp.array([2.0, 2.0])\n", + "initial_momentum = jnp.array([0.5, -0.3])\n", + "\n", + "# Transform initial conditions for the standard Gaussian\n", + "transformed_position, transformed_momentum = transform_coordinates(initial_position, initial_momentum, cov)\n", + "\n", + "# Create initial states\n", + "original_state = integrators.new_integrator_state(logdensity_fn, initial_position, initial_momentum)\n", + "cov_mass_state = integrators.new_integrator_state(logdensity_fn, initial_position, initial_momentum)\n", + "standard_state = integrators.new_integrator_state(standard_logdensity_fn, transformed_position, transformed_momentum)\n", + "\n", + "# Run the integrators\n", + "step_size = 0.1\n", + "num_steps = 50\n", + "\n", + "original_states = run_integrator(original_state, original_integrator, step_size, num_steps)\n", + "cov_mass_states = run_integrator(cov_mass_state, cov_mass_integrator, step_size, num_steps)\n", + "standard_states = run_integrator(standard_state, standard_integrator, step_size, num_steps)\n", + "\n", + "# Extract positions\n", + "original_positions = jnp.array([state.position for state in original_states])\n", + "cov_mass_positions = jnp.array([state.position for state in cov_mass_states])\n", + "standard_positions = jnp.array([state.position for state in standard_states])\n", + "\n", + "# Transform standard positions back to original space\n", + "transformed_standard_positions = jnp.array([\n", + " inverse_transform_coordinates(pos, jnp.zeros(2), cov)[0] for pos in standard_positions\n", + "])\n", + "\n", + "# Compare the trajectories\n", + "def plot_equivalent_trajectories():\n", + " x = np.linspace(-4, 4, 100)\n", + " y = np.linspace(-4, 4, 100)\n", + " X, Y = np.meshgrid(x, y)\n", + " Z = np.zeros((100, 100))\n", + " for i in range(100):\n", + " for j in range(100):\n", + " Z[i, j] = np.exp(logdensity_fn(np.array([X[i, j], Y[i, j]])))\n", + " \n", + " plt.figure(figsize=(15, 5))\n", + " \n", + " # Plot original Gaussian with unit mass matrix\n", + " plt.subplot(1, 3, 1)\n", + " plt.contour(X, Y, Z, levels=20)\n", + " plt.plot(original_positions[:, 0], original_positions[:, 1], 'r-', label='Trajectory')\n", + " plt.plot(original_positions[0, 0], original_positions[0, 1], 'go', label='Start')\n", + " plt.plot(original_positions[-1, 0], original_positions[-1, 1], 'bo', label='End')\n", + " plt.xlabel('x')\n", + " plt.ylabel('y')\n", + " plt.title('Original Gaussian\\nUnit Mass Matrix')\n", + " plt.legend()\n", + " plt.axis('equal')\n", + " \n", + " # Plot original Gaussian with mass matrix = covariance\n", + " plt.subplot(1, 3, 2)\n", + " plt.contour(X, Y, Z, levels=20)\n", + " plt.plot(cov_mass_positions[:, 0], cov_mass_positions[:, 1], 'r-', label='Trajectory')\n", + " plt.plot(cov_mass_positions[0, 0], cov_mass_positions[0, 1], 'go', label='Start')\n", + " plt.plot(cov_mass_positions[-1, 0], cov_mass_positions[-1, 1], 'bo', label='End')\n", + " plt.xlabel('x')\n", + " plt.ylabel('y')\n", + " plt.title('Original Gaussian\\nMass Matrix = Covariance')\n", + " plt.legend()\n", + " plt.axis('equal')\n", + " \n", + " # Plot standard Gaussian with unit mass matrix (transformed back)\n", + " plt.subplot(1, 3, 3)\n", + " plt.contour(X, Y, Z, levels=20)\n", + " plt.plot(transformed_standard_positions[:, 0], transformed_standard_positions[:, 1], 'r-', label='Trajectory')\n", + " plt.plot(transformed_standard_positions[0, 0], transformed_standard_positions[0, 1], 'go', label='Start')\n", + " plt.plot(transformed_standard_positions[-1, 0], transformed_standard_positions[-1, 1], 'bo', label='End')\n", + " plt.xlabel('x')\n", + " plt.ylabel('y')\n", + " plt.title('Standard Gaussian (Transformed)\\nUnit Mass Matrix')\n", + " plt.legend()\n", + " plt.axis('equal')\n", + " \n", + " plt.tight_layout()\n", + " plt.show()\n", + "\n", + "plot_equivalent_trajectories()\n", + "\n", + "# Calculate the differences between trajectories\n", + "original_cov_mass_diff = jnp.mean(jnp.abs(original_positions - cov_mass_positions))\n", + "original_standard_diff = jnp.mean(jnp.abs(original_positions - transformed_standard_positions))\n", + "cov_mass_standard_diff = jnp.mean(jnp.abs(cov_mass_positions - transformed_standard_positions))\n", + "\n", + "print(f\"Average difference between original and cov_mass trajectories: {original_cov_mass_diff:.6f}\")\n", + "print(f\"Average difference between original and standard trajectories: {original_standard_diff:.6f}\")\n", + "print(f\"Average difference between cov_mass and standard trajectories: {cov_mass_standard_diff:.6f}\")\n", + "\n", + "# Plot the differences over time\n", + "plt.figure(figsize=(12, 6))\n", + "time = np.arange(num_steps) * step_size\n", + "plt.plot(time, jnp.abs(original_positions - cov_mass_positions).mean(axis=1), 'r-', label='Original vs Cov Mass')\n", + "plt.plot(time, jnp.abs(original_positions - transformed_standard_positions).mean(axis=1), 'b-', label='Original vs Standard')\n", + "plt.plot(time, jnp.abs(cov_mass_positions - transformed_standard_positions).mean(axis=1), 'g-', label='Cov Mass vs Standard')\n", + "plt.xlabel('Time')\n", + "plt.ylabel('Average Absolute Difference')\n", + "plt.title('Trajectory Differences Over Time')\n", + "plt.legend()\n", + "plt.grid(True)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Conclusion\n", + "\n", + "In this notebook, we've demonstrated how to use the velocity verlet integrator from Blackjax to simulate Hamiltonian dynamics for a Gaussian target distribution. We've shown that:\n", + "\n", + "1. The integrator can be used to simulate the trajectory of a particle in the potential energy landscape defined by the negative log-density of the target distribution.\n", + "2. The integrator approximately conserves energy, with small errors due to the numerical approximation.\n", + "3. The integrator is time-reversible, meaning that running it forward and then backward returns to the initial state (up to numerical errors).\n", + "4. Using a mass matrix that is the inverse of the covariance matrix is equivalent to using a unit mass matrix on a Gaussian with unit covariance.\n", + "\n", + "These properties make the velocity verlet integrator a good choice for Hamiltonian Monte Carlo, where we want to simulate Hamiltonian dynamics to propose new states in the Markov chain. The equivalence between mass matrices and covariance matrices is particularly useful for designing efficient samplers, as it allows us to transform complex target distributions into simpler ones with isotropic dynamics." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.9" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +}