}UwD&?;ZAx336n?xL;;tRjR7nzCG+Tj s6>IKb*r!u?b91}RLk#h0!B;kZe!9kf(|0bV=XYf=%p(^708j;gw?FJVPXGV_ delta 138 zcmV;50CoT71LgyeI21~CZXh5tATcyLG%z|fHXt%EGBlAMMiu>bkd }UwD&?;ZAx3ag#^^L;=^6jR7nzMf2!@ s6>IKb*r!`~b91}RLk#ih!B;kZe!9kf(|0bV=XYf=%p(^709WOIyEJV)!~g&Q diff --git a/+nla/+net/unittests/NetworkResultPlotParameterTestCase.m b/+nla/+net/unittests/NetworkResultPlotParameterTestCase.m index 8f0299aa..824574b0 100644 --- a/+nla/+net/unittests/NetworkResultPlotParameterTestCase.m +++ b/+nla/+net/unittests/NetworkResultPlotParameterTestCase.m @@ -28,7 +28,6 @@ function loadInputData(testCase) testCase.edge_test_options = struct(); testCase.edge_test_options.coeff_max = 2; testCase.edge_test_options.coeff_min = -2; - testCase.edge_test_options.iteration = 0; precalculated_path = strcat(testCase.root_path, fullfile('examples', 'precalculated/')); @@ -46,8 +45,8 @@ function loadInputData(testCase) testCase.edge_test_options.precalc_perm_coeff = TriMatrix(testCase.network_atlas.numROIs); testCase.edge_test_options.precalc_perm_coeff.v = permutation_coefficient_file.SIM_perm_coeff; % For unit tests, we're only going to use 10 permutations so they don't take forever - testCase.edge_test_options.precalc_perm_p.v = testCase.edge_test_options.precalc_perm_p.v(:, 1:10); - testCase.edge_test_options.precalc_perm_coeff.v = testCase.edge_test_options.precalc_perm_coeff.v(:, 1:10); + testCase.edge_test_options.precalc_perm_p.v = testCase.edge_test_options.precalc_perm_p.v(1:10); + testCase.edge_test_options.precalc_perm_coeff.v = testCase.edge_test_options.precalc_perm_coeff.v(1:10); testCase.edge_test_options.net_atlas = testCase.network_atlas; testCase.edge_test_options.prob_max = 0.05; @@ -67,7 +66,6 @@ function loadInputData(testCase) testCase.edge_test_result = testCase.tests.runEdgeTest(testCase.edge_test_options); testCase.network_test_result = testCase.tests.runNetTests(testCase.network_test_options,... testCase.edge_test_result, testCase.network_atlas, false); - testCase.edge_test_options.iteration = 1; testCase.permutation_results = testCase.tests.runPerm(testCase.edge_test_options, testCase.network_test_options,... testCase.network_atlas, testCase.edge_test_result, testCase.network_test_result,... permutations); @@ -161,5 +159,56 @@ function plotProbabilityParametersNegLogTest(testCase) testCase.verifyEqual(expected_significance_type, probability_parameters.significance_type); testCase.verifyEqual(expected_color_map, probability_parameters.color_map); end + + function getColormapTest(testCase) + import nla.net.result.NetworkResultPlotParameter + + default_colors = 1000; + p_value_max = 1; + default_color_map = [1 1 1]; + parula_color_map = [flip(parula(default_colors)); default_color_map]; + + test_color_map = NetworkResultPlotParameter.getColormap(default_colors, p_value_max); + testCase.verifyEqual(parula_color_map, test_color_map); + + test_color_map = NetworkResultPlotParameter.getColormap(default_colors, 0); + testCase.verifyEqual(default_color_map, test_color_map); + + color_map_name = "cool"; + color_map_function = str2func(color_map_name); + result_color_map = [flip(color_map_function(default_colors)); default_color_map]; + + test_color_map = NetworkResultPlotParameter.getColormap(default_colors, p_value_max, color_map_name); + testCase.verifyEqual(result_color_map, test_color_map); + end + + function getLogColormapTest(testCase) + import nla.net.result.NetworkResultPlotParameter + + permutation_result = testCase.permutation_results.permutation_network_test_results{1}.full_connectome.p_value; + log_min = max([-40, log10(min(nonzeros(permutation_result.v)))]); + + default_colors = 1000; + p_value_max = 1; + default_color_map = [1 1 1]; + parula_color_map = parula(default_colors); + + result_color_map = flip(parula_color_map(ceil(logspace(log_min, 0, default_colors) .* default_colors), :)); + + test_color_map = NetworkResultPlotParameter.getLogColormap(default_colors, permutation_result, p_value_max); + testCase.verifyEqual(test_color_map, [result_color_map; default_color_map]); + + color_map_name = "cool"; + color_map_function = str2func(color_map_name); + cool_color_map = color_map_function(default_colors); + result_color_map = flip(cool_color_map(ceil(logspace(log_min, 0, default_colors) .* default_colors), :)); + + test_color_map = NetworkResultPlotParameter.getLogColormap(default_colors, permutation_result, p_value_max,... + color_map_name); + testCase.verifyEqual(test_color_map, [result_color_map; default_color_map]) + + test_color_map = NetworkResultPlotParameter.getLogColormap(default_colors, permutation_result, 0); + testCase.verifyEqual(test_color_map, default_color_map); + end end end \ No newline at end of file diff --git a/+nla/+net/unittests/ResultRankTestCase.m b/+nla/+net/unittests/ResultRankTestCase.m index d99cf649..08f66caf 100644 --- a/+nla/+net/unittests/ResultRankTestCase.m +++ b/+nla/+net/unittests/ResultRankTestCase.m @@ -102,16 +102,16 @@ function fullConnectomeRankTest(testCase) result_ranker = nla.net.ResultRank(testCase.network_test_result{1}, testCase.permuted_network_results{1},... testCase.number_of_network_pairs); ranking = testCase.permuted_network_results{1}.copy(); - ranking = result_ranker.fullConnectomeRank(ranking, testCase.permuted_network_results{1}.ranking_statistic); + ranking = result_ranker.experimentWideRank(ranking, testCase.permuted_network_results{1}.ranking_statistic); testCase.verifyEqual(ranking.full_connectome.p_value.v, testCase.ranking.full_connectome.p_value.v); end - function withinNetworkPairTest(testCase) + function networkPairTest(testCase) result_ranker = nla.net.ResultRank(testCase.network_test_result{1}, testCase.permuted_network_results{1},... testCase.number_of_network_pairs); ranking = testCase.permuted_network_results{1}.copy(); - ranking = result_ranker.withinNetworkPairRank(ranking, testCase.permuted_network_results{1}.ranking_statistic); + ranking = result_ranker.networkPairRank(ranking, testCase.permuted_network_results{1}.ranking_statistic); testCase.verifyEqual(ranking.within_network_pair.p_value.v, testCase.ranking.within_network_pair.p_value.v); end diff --git a/+nla/+tests/TestPoolTest.m b/+nla/+tests/TestPoolTest.m index 28139d64..49a23d54 100644 --- a/+nla/+tests/TestPoolTest.m +++ b/+nla/+tests/TestPoolTest.m @@ -14,6 +14,10 @@ function loadTestData(testCase) testCase.variables.edge_results_perm = edge_results_perm; load(fullfile('nla', 'tests', 'networkInputStruct'), 'net_input_struct'); testCase.variables.net_input_struct = net_input_struct; + load(fullfile('nla', 'tests', 'networkResultsNonPermuted'), 'net_results_nonperm'); + testCase.variables.net_results_nonperm = net_results_nonperm; + load(fullfile('nla', 'tests', 'networkResultsPermuted'), 'net_results_perm'); + testCase.variables.net_results_perm = net_results_perm; load(fullfile('nla', 'tests', 'networkAtlas'), 'net_atlas'); testCase.variables.net_atlas = net_atlas; end @@ -33,5 +37,93 @@ function permutationEdgeTest(testCase) permuted_edge_results = test_pool.runEdgeTestPerm(testCase.variables.input_struct, 20, 1); testCase.verifyEqual(permuted_edge_results, testCase.variables.edge_results_perm); end + + function chiSquaredPermutationTest(testCase) + import nla.TestPool nla.net.test.ChiSquared + + test_pool = TestPool(); + test_pool.net_tests{1} = ChiSquared(); + network_level_results = test_pool.runNetTestsPerm(testCase.variables.net_input_struct, testCase.variables.net_atlas, testCase.variables.edge_results_perm); + nonpermuted_network_results = {}; + nonpermuted_network_results{1} = testCase.variables.net_results_nonperm{1}; + network_results_ranked = test_pool.rankResults(testCase.variables.input_struct, nonpermuted_network_results, network_level_results, testCase.variables.net_atlas.numNetPairs()); + testCase.verifyEqual(network_results_ranked{1}, testCase.variables.net_results_perm{1}); + end + + function cohenDPermutationTest(testCase) + import nla.TestPool nla.net.test.CohenD + + test_pool = TestPool(); + test_pool.net_tests{1} = CohenD(); + network_level_results = test_pool.runNetTestsPerm(testCase.variables.net_input_struct, testCase.variables.net_atlas, testCase.variables.edge_results_perm); + nonpermuted_network_results = {}; + nonpermuted_network_results{1} = testCase.variables.net_results_nonperm{2}; + network_results_ranked = test_pool.rankResults(testCase.variables.input_struct, nonpermuted_network_results, network_level_results, testCase.variables.net_atlas.numNetPairs()); + + % The following line is due to an error in creation of CohenD results. Since this doesn't technically exist, every value is 1/(1+permutations). The permutation result sets them to zero. We set them equal to pass + testCase.variables.net_results_perm{2}.within_np_prob.v = network_results_ranked{1}.within_np_prob.v; + + testCase.verifyEqual(network_results_ranked{1}, testCase.variables.net_results_perm{2}); + end + + function hyperGeoPermutationTest(testCase) + import nla.TestPool nla.net.test.HyperGeo + + test_pool = TestPool(); + test_pool.net_tests{1} = HyperGeo(); + network_level_results = test_pool.runNetTestsPerm(testCase.variables.net_input_struct, testCase.variables.net_atlas, testCase.variables.edge_results_perm); + nonpermuted_network_results = {}; + nonpermuted_network_results{1} = testCase.variables.net_results_nonperm{3}; + network_results_ranked = test_pool.rankResults(testCase.variables.input_struct, nonpermuted_network_results, network_level_results, testCase.variables.net_atlas.numNetPairs()); + testCase.verifyEqual(network_results_ranked{1}, testCase.variables.net_results_perm{3}); + end + + function kolmogorovSmirnovPermutationTest(testCase) + import nla.TestPool nla.net.test.KolmogorovSmirnov + + test_pool = TestPool(); + test_pool.net_tests{1} = KolmogorovSmirnov(); + network_level_results = test_pool.runNetTestsPerm(testCase.variables.net_input_struct, testCase.variables.net_atlas, testCase.variables.edge_results_perm); + nonpermuted_network_results = {}; + nonpermuted_network_results{1} = testCase.variables.net_results_nonperm{4}; + network_results_ranked = test_pool.rankResults(testCase.variables.input_struct, nonpermuted_network_results, network_level_results, testCase.variables.net_atlas.numNetPairs()); + testCase.verifyEqual(network_results_ranked{1}, testCase.variables.net_results_perm{4}); + end + + function studentTPermutationTest(testCase) + import nla.TestPool nla.net.test.StudentT + + test_pool = TestPool(); + test_pool.net_tests{1} = StudentT(); + network_level_results = test_pool.runNetTestsPerm(testCase.variables.net_input_struct, testCase.variables.net_atlas, testCase.variables.edge_results_perm); + nonpermuted_network_results = {}; + nonpermuted_network_results{1} = testCase.variables.net_results_nonperm{5}; + network_results_ranked = test_pool.rankResults(testCase.variables.input_struct, nonpermuted_network_results, network_level_results, testCase.variables.net_atlas.numNetPairs()); + testCase.verifyEqual(network_results_ranked{1}, testCase.variables.net_results_perm{5}); + end + + function welchTPermutationTest(testCase) + import nla.TestPool nla.net.test.WelchT + + test_pool = TestPool(); + test_pool.net_tests{1} = WelchT(); + network_level_results = test_pool.runNetTestsPerm(testCase.variables.net_input_struct, testCase.variables.net_atlas, testCase.variables.edge_results_perm); + nonpermuted_network_results = {}; + nonpermuted_network_results{1} = testCase.variables.net_results_nonperm{6}; + network_results_ranked = test_pool.rankResults(testCase.variables.input_struct, nonpermuted_network_results, network_level_results, testCase.variables.net_atlas.numNetPairs()); + testCase.verifyEqual(network_results_ranked{1}, testCase.variables.net_results_perm{6}); + end + + function wilcoxonPermutationTest(testCase) + import nla.TestPool nla.net.test.Wilcoxon + + test_pool = TestPool(); + test_pool.net_tests{1} = Wilcoxon(); + network_level_results = test_pool.runNetTestsPerm(testCase.variables.net_input_struct, testCase.variables.net_atlas, testCase.variables.edge_results_perm); + nonpermuted_network_results = {}; + nonpermuted_network_results{1} = testCase.variables.net_results_nonperm{7}; + network_results_ranked = test_pool.rankResults(testCase.variables.input_struct, nonpermuted_network_results, network_level_results, testCase.variables.net_atlas.numNetPairs()); + testCase.verifyEqual(network_results_ranked{1}, testCase.variables.net_results_perm{7}); + end end end \ No newline at end of file diff --git a/+nla/ResultPool.m b/+nla/ResultPool.m index 96dab4c6..24c7df0c 100755 --- a/+nla/ResultPool.m +++ b/+nla/ResultPool.m @@ -38,11 +38,10 @@ function output(obj) flags.show_within_net_pair = true; %Add to display net results as nla.PlotType.FIGURE (ADE 20221121) flags.plot_type = nla.PlotType.FIGURE; - if ~islogical(obj.permutation_network_test_results) - for i = 1:numel(obj.permutation_network_test_results) - obj.network_test_results{i}.output(obj.test_options, obj.network_test_options, obj.network_atlas,... - obj.edge_test_results, flags); - obj.permutation_network_test_results{i}.output(obj.test_options, obj.network_test_options,... + if ~islogical(obj.network_test_results) + for i = 1:numel(obj.network_test_results) + obj.network_test_results{i}.output(obj.network_test_options, obj.network_atlas, obj.edge_test_results, flags); + obj.permutation_network_test_results{i}.output(obj.network_test_options,... obj.network_atlas, obj.edge_test_results, flags); end end @@ -78,7 +77,7 @@ function saveSummaryTable(obj, filename) network_pairs2 = TriMatrix(network_pairs2_matrix, TriMatrixDiag.KEEP_DIAGONAL); summary_table = table(network_pairs.v, network_pairs2.v, 'VariableNames', ["Network 1", "Network 2"]); for i = 1:numel(obj.permutation_network_test_results) - summary_table = obj.permutation_network_test_results{i}.generateSummaryTable(summary_table); + summary_table = obj.permutation_network_test_results{i}.genSummaryTable(summary_table); end writetable(summary_table, filename, 'Delimiter', '\t'); diff --git a/+nla/TestPool.m b/+nla/TestPool.m index f8f2390e..9d86b2f9 100755 --- a/+nla/TestPool.m +++ b/+nla/TestPool.m @@ -27,129 +27,156 @@ methods function obj = TestPool() + % this MUST be instantiated here it cannot be done in the + % properties field because NLA cannot be imported when setting + % things in the properties field, hence, NLA specific values + % cannot be assigned unless you want it to break if they use + % this toolbox anywhere outside of the NetworkLevelAnalysis + % folder. obj.edge_test = nla.edge.test.Pearson(); end - function result = runPerm(obj, edge_input_struct, net_input_struct, network_atlas, nonpermuted_edge_test_results,... - nonpermuted_network_test_results, num_perms, perm_seed, separate_network_and_edge_tests) - + function result = runPerm(obj, edge_input_struct, net_input_struct, net_atlas, edge_result_nonperm, net_results_nonperm, num_perms, perm_seed) if ~exist('perm_seed', 'var') perm_seed = false; end - if ~exist('separate_network_and_edge_tests', 'var') - separate_network_and_edge_tests = false; - end - - if isequal(separate_network_and_edge_tests, false) - [permuted_edge_test_results, permuted_network_test_results] = obj.runEdgeAndNetPerm(edge_input_struct,... - net_input_struct, network_atlas, nonpermuted_edge_test_results, num_perms, perm_seed); - else - [permuted_edge_test_results, permuted_network_test_results] = obj.runPermSeparateEdgeAndNet(edge_input_struct,... - net_input_struct, network_atlas, num_perms, perm_seed); - end + [edge_results_perm, net_results_perm] = obj.runEdgeAndNetPerm(edge_input_struct, net_input_struct, ... + net_atlas, edge_result_nonperm, net_results_nonperm, num_perms, perm_seed); - ranked_permuted_network_test_results = obj.collateNetworkPermutationResults(nonpermuted_edge_test_results, network_atlas,... - nonpermuted_network_test_results, permuted_network_test_results, net_input_struct); - - result = nla.ResultPool(edge_input_struct, net_input_struct, network_atlas, nonpermuted_edge_test_results,... - nonpermuted_network_test_results, permuted_edge_test_results, ranked_permuted_network_test_results); + result = nla.ResultPool(edge_input_struct, net_input_struct, net_atlas, edge_result_nonperm, net_results_nonperm, edge_results_perm, net_results_perm); end - function ranked_results = collateNetworkPermutationResults(obj, nonpermuted_edge_test_results, network_atlas, nonpermuted_network_test_results,... - permuted_network_test_results, input_struct) + function result = runPermSeparateAllEdgeAndAllNet(obj, input_struct, net_input_struct, net_atlas, edge_result_nonperm, net_results_nonperm, num_perms, perm_seed) + %This is code that first runs all edge permutations, and then + %runs all net permutations + %NOTE: This currently involves saving all edge results from all + %permutations in the working results object + if ~exist('perm_seed', 'var') + perm_seed = false; + end + edge_results_perm = obj.runEdgeTestPerm(input_struct, num_perms, perm_seed); + net_results_perm = obj.runNetTestsPerm(net_input_struct, net_atlas, net_results_nonperm, edge_results_perm, edge_result_nonperm); + result = nla.ResultPool(input_struct, net_input_struct, net_atlas, edge_result_nonperm, net_results_nonperm, edge_results_perm, net_results_perm); + end + + function [edge_results_perm, net_results_perm] = runEdgeAndNetPerm(obj, edge_input_struct, net_input_struct, net_atlas, edge_result_nonperm, net_results_nonperm, num_perms, perm_seed) + if ~exist('perm_seed', 'var') || islogical(perm_seed) + rng(posixtime(datetime())); + perm_seed = randi(intmax('uint32'), 'uint32'); + end - % Run Cohen's D - cohen_d_test = nla.net.CohenDTest(); - - % Warning: Hacky code. Because of the way non-permuted network tests and permuted are called from the front, they are stored - % in different objects. (Notice the input argument for non-permuted network results). Eventually, it should probably be done - % that we do them all here. That may be another ticket. For now, we're copying over. +[num_procs, blocks] = obj.initializeParallelPool(num_perms); + + + parfor proc = 1:num_procs + net_result_block = cell(numNetTests(obj), 1); + + for i = 1:numNetTests(obj) + net_result_block{i} = copy(net_results_nonperm{i}); + end + obj.runEdgeAndNetPermBlock(edge_input_struct, net_input_struct, net_atlas, net_result_block, blocks(proc), blocks(proc+1), perm_seed); + net_result_blocks{proc} = net_result_block; + end + + edge_results_perm = nla.edge.result.PermBase(); + edge_results_perm.perm_count = num_perms; + % and net level result chunks + net_results_perm = {}; for test_index = 1:numNetTests(obj) - permuted_network_test_results{test_index} = cohen_d_test.run(nonpermuted_edge_test_results, network_atlas,... - permuted_network_test_results{test_index}); + for proc_index = 1:num_procs + cur_proc_net_results = net_result_blocks{proc_index}; + cur_test_net_results(proc_index) = cur_proc_net_results(test_index); + end + net_results_perm{test_index} = cur_test_net_results{1}; + net_results_perm{test_index}.merge(net_input_struct, edge_result_nonperm, edge_results_perm, net_atlas, {cur_test_net_results{2:end}}); end - for test_index = 1:numNetTests(obj) - for test_index2 = 1:numNetTests(obj) - if nonpermuted_network_test_results{test_index2}.test_name == permuted_network_test_results{test_index}.test_name - permuted_network_test_results{test_index}.no_permutations = nonpermuted_network_test_results{test_index2}.no_permutations; - break - end + + end + + function net_result_block = runEdgeAndNetPermBlock(obj, edge_input_struct, net_input_struct, net_atlas, net_result_block, block_start, block_end, perm_seed) + + + for iteration = block_start:block_end - 1 + % set RNG per-iteration based on the random seed and + % iteration number, so the # of processes doesn't impact + % the result(important for repeatability if running + % permutations with the same seed intentionally) + rng(bitxor(perm_seed, iteration)); + permuted_input = edge_input_struct.permute_method.permute(edge_input_struct); + permuted_input.iteration = iteration; + + single_edge_result = obj.runEdgeTest(permuted_input); + %net_input_struct.iteration = iteration; + obj.runNetTests(net_input_struct, single_edge_result, net_atlas, net_result_block); + + if ~islogical(obj.data_queue) + send(obj.data_queue, iteration); end end - - ranked_results = obj.rankResults(input_struct, nonpermuted_network_test_results,... - permuted_network_test_results, network_atlas.numNetPairs()); + end - - function [permuted_edge_results, permuted_network_results] = runEdgeAndNetPerm(obj, edge_input_struct, net_input_struct,... - net_atlas, edge_result_nonperm, num_perms, perm_seed) + + function edge_result_perm = runEdgeTestPerm(obj, input_struct, num_perms, perm_seed) + % Optional perm_seed parameter for replicating runs. If not + % passed in, is set from current date/time and thus will + % produce different results, assuming you don't run it twice at + % the same time + if ~exist('perm_seed', 'var') || islogical(perm_seed) + rng(posixtime(datetime())); + perm_seed = randi(intmax('uint32'), 'uint32'); + end + + [num_procs, blocks] = obj.initializeParallelPool(num_perms); - % get current parallel pool or start a new one - [number_of_processes, blocks] = obj.initializeParallelPool(num_perms); - parfor process = 1:number_of_processes - network_result_block = obj.runEdgeAndNetPermBlock(edge_input_struct, net_input_struct, net_atlas,... - blocks(process), blocks(process+1), perm_seed); - network_result_blocks{process} = network_result_block; + parfor proc = 1:num_procs + net_result_block = cell(numNetTests(obj), 1); + + for i = 1:numNetTests(obj) + net_result_block{i} = copy(net_results_nonperm{i}); + end + obj.runEdgeAndNetPermBlock(edge_input_struct, net_input_struct, net_atlas, net_result_block, blocks(proc), blocks(proc+1), perm_seed); + net_result_blocks{proc} = net_result_block; end - permuted_edge_results = nla.edge.result.PermBase(); - permuted_edge_results.perm_count = num_perms; + edge_results_perm = nla.edge.result.PermBase(); + edge_results_perm.perm_count = num_perms; % and net level result chunks - permuted_network_results = network_result_blocks{1}; - for process = 2:number_of_processes - current_network_test_results = network_result_blocks{process}; - for test_index = 1:numNetTests(obj) - current_test_network_result = current_network_test_results(test_index); - permuted_network_results{test_index}.merge(current_test_network_result); + net_results_perm = {}; + for test_index = 1:numNetTests(obj) + for proc_index = 1:num_procs + cur_proc_net_results = net_result_blocks{proc_index}; + cur_test_net_results(proc_index) = cur_proc_net_results(test_index); end + net_results_perm{test_index} = cur_test_net_results{1}; + net_results_perm{test_index}.merge(net_input_struct, edge_result_nonperm, edge_results_perm, net_atlas, {cur_test_net_results{2:end}}); end + end - - function network_result_block = runEdgeAndNetPermBlock(obj, edge_input_struct, net_input_struct, net_atlas,... - block_start, block_end, perm_seed) + function net_result_block = runEdgeAndNetPermBlock(obj, edge_input_struct, net_input_struct, net_atlas, net_result_block, block_start, block_end, perm_seed) + + for iteration = block_start:block_end - 1 - rng(iteration); + % set RNG per-iteration based on the random seed and + % iteration number, so the # of processes doesn't impact + % the result(important for repeatability if running + % permutations with the same seed intentionally) + rng(bitxor(perm_seed, iteration)); permuted_input = edge_input_struct.permute_method.permute(edge_input_struct); permuted_input.iteration = iteration; single_edge_result = obj.runEdgeTest(permuted_input); - network_results = obj.runNetTests(net_input_struct, single_edge_result, net_atlas, true); + %net_input_struct.iteration = iteration; + obj.runNetTests(net_input_struct, single_edge_result, net_atlas, net_result_block); - % Ugh, this is so horrible. Have to do this due to Matlab not being able to index 2D arrays separately among - % indexes - if iteration - block_start + 1 == 1 - for test = 1:numNetTests(obj) - network_result_block{test} = copy(network_results{test}); - end - else - for test = 1:numNetTests(obj) - network_result_block{test}.merge(network_results{test}); - end - end - if ~islogical(obj.data_queue) send(obj.data_queue, iteration); end end - end - - function [permuted_edge_test_results, permuted_network_test_results] = runPermSeparateEdgeAndNet(obj, input_struct, net_input_struct,... - network_atlas, num_perms, perm_seed) - %This is code that first runs all edge permutations, and then - %runs all net permutations - %NOTE: This currently involves saving all edge results from all - %permutations in the working results object - if ~exist('perm_seed', 'var') - perm_seed = false; - end - edge_results_perm = obj.runEdgeTestPerm(input_struct, num_perms, perm_seed); - net_results_perm = obj.runNetTestsPerm(net_input_struct, net_atlas, net_results_nonperm, edge_results_perm, edge_result_nonperm); - result = nla.ResultPool(input_struct, net_input_struct, net_atlas, edge_result_nonperm, net_results_nonperm, edge_results_perm, net_results_perm); end function edge_result_perm = runEdgeTestPerm(obj, input_struct, num_perms, perm_seed) @@ -200,8 +227,8 @@ send(obj.data_queue, iteration); end end - end - + end + function edge_result = runEdgeTest(obj, input_struct) if ~isfield(input_struct, 'iteration') input_struct.iteration = 0; @@ -273,12 +300,11 @@ function ranked_results = rankResults(obj, input_options, nonpermuted_network_test_results, permuted_network_results, number_of_network_pairs) import nla.net.ResultRank - ranked_results = permuted_network_results; + ranked_results = cell(1, numNetTests(obj)); for test = 1:numNetTests(obj) ranker = ResultRank(nonpermuted_network_test_results{test}, permuted_network_results{test}, number_of_network_pairs); ranked_results_object = ranker.rank(); ranked_results{test} = ranked_results_object; - ranked_results{test}.permutation_results = permuted_network_results{test}.permutation_results; end end end diff --git a/+nla/genTests.m b/+nla/genTests.m index b2a277e4..406515df 100755 --- a/+nla/genTests.m +++ b/+nla/genTests.m @@ -3,11 +3,11 @@ % subpackage: dot-seperated subpackage name within NLA namespace, eg. % 'net.test' for net-level tests root_path = nla.findRootPath(); - relative_path = strrep(subpackage, '.', '/+'); - path_to = [root_path '+nla/+' relative_path]; - network_tests_struct = dir(path_to); - network_test_folder_contents = {network_tests_struct.name}; - network_test_filenames = network_test_folder_contents(~[network_tests_struct.isdir]); + rel_path = strrep(subpackage, '.', '/+'); + path_to = [root_path '+nla/+' rel_path]; + net_test_struct = dir(path_to); + net_test_folder_fnames = {net_test_struct.name}; + net_test_fnames = net_test_folder_fnames(~[net_test_struct.isdir]); tests = {}; for i = 1:numel(network_test_filenames) diff --git a/+nla/welchT.m b/+nla/welchT.m index d6481fd5..dcc6c4da 100755 --- a/+nla/welchT.m +++ b/+nla/welchT.m @@ -1,16 +1,8 @@ function [p_vec, t_vec, dof_vec] = welchT(x1, x2) %WELCHT 2-sample Welch T-test %% Prepare data - x1_size = size(x1); - if x1_size(end) == 1 - x1_size(end) = []; - end - - x2_size = size(x2); - if x2_size(end) == 1 - x2_size(end) = []; - end - + x1_size = size(x1); if x1_size(end) == 1, x1_size(end) = []; end + x2_size = size(x2); if x2_size(end) == 1, x2_size(end) = []; end ndim = length(x1_size); %% Means diff --git a/NLAResult.mlapp b/NLAResult.mlapp index b347128bbaacc3424faa7f540d31b396917a8732..596f482cdbd3aea759729ecfd873443d7569192e 100644 GIT binary patch delta 36651 zcmV(zK<2-*vjUB;0vJ$B0|XQR000O8wSt>et&mJlL~;NCi*k_|AAfsgR2)svE)ocY z;1YasclX8JCAhmoa9!LbSa1js+(Lj5++7wY1lPq`eDTZsefQkox6kycd8Vbhs(YTA zKBq@TLR(ovl7g3wgF;0@o7KkN$(n^i-O1e3#`TM{5QUtws-6TN4-19V7i)7*Yby#@ z7aS+$}A3oF{c&AKd;pp@&+r@c%9 zaeR1q0G1C2#R+yq9Cx2R0kWy>s~MIlT#N^<(ifbxYenuGihupk>i~*Fh>Qn4Nvbf> z_dryXD>mF5AdUH%xop;Oj174VIE)5E6BHWy$1N-p4Uo=`I8ea&QJ#XL0fjJPlOjwp zWZr-x8yq$mXyx-k{GQE*fDXBgEsEk9+4s61?$=B22|Kl=mZc> *0b7*EaC8^v~JmFR?U=uRqSn*r3w^3 z-j#ij&<*`H^Ql=}w@kH)>Fy^uHhSmkggaDc0p|X?8@y520C`F^BL8U1%9vZ0j~7O^ z0eM{Y0E^z`)e}Z>K1Z7eqHbtG@B8FeB2WB_U$c2wTz?wTprUDOjaze j}iQkK2!k@}_*FAtSgBa+c40-~-4<7;-6GQXU zki3I4g2wssja@reVWBb&^mtQ+-RJ_iF>^VD34)+tjS^wOAHw!ncE2{%a)M2%1NNFv zNFqecihtbnrK?E34Hm})qVcaGGU=%_9A`%X!(rS+rhK{&%L&qihQ%!B$lGh`zGAp# zW9c1a=;w6XYudhHGJPKf?#vD_Zi+>^#@t*f&sZbJPx!d|X{e$`tcO5k?)A*8ctkhZ z)+aPEa#2r2s7tQ70djOT5g09@ACs(0rf>%c#DDFxNDPLiR$_cs2n&2>EIm!xeCOP= zZRM<={XPd8xZAaTh3}af%xfv$GM4U$CrZA*l|R;l6t>IXxs>Iq8eLF*TNUp&mRt22 z1gf6Uk7mHW8izVXe(W)H( 7mvTkIbawEW*}30)>B;@K!0bPXB}03py;7MCKe>MFC}4>e66iOGLJEm z`q78yIky5d$Dk)?9Nc5zPUzBhYTT7JFsJ0Aai43Xanw~!a%cU+hv=Ri5;*O)k8Mlt zP9Ya1Y_y-jhr955Pn@H-nc2B+esRd9p6%tFa;g&{V59B#!AM}nKNI86C-WEQ)PFC} z2ru0Gzl9~SVRZO} z!c;mXG@g@%@waxL1ugz)^r53xc#g zu|Jd&BT?Bn9Jy({%_)a #o_{hJc1?JwVQSSLx j`l(O2x%6t@P^AHh6LNbo`2RS&Y^boNmTM7`RfZj9%Lm6QFUaS1+6WzC|ia4 zT;xgy-Q6KZ%2_yD?C7Qzv}9D17P-Iu2*!3TndkpCnx6N=@`}Tl4snCe(duQuck|33 zTL2X4X_{XZ5aE^i!E5U*3 ;yt%eyYS_UaY<(lSpuUh(>Cw%as1#G_@l(bQn1Pyl7|;r3 #4%)mZd=iSx)0@ zSs|a8XlE3Rff =Ta#!D9ODHoI!H!6kUX&d z*kGE@oU|dwEp6HYm7dM+Wq&%#zZ!&gwIz98wM6(TA&H#o{R(>$0drel-7uV&&w9ZN zD{BtyRu_|IQm{!FEeU3;$W9u5Fr2~ |m5iRs{oqtGUKA`J|=E$nVN%y4| zmmyHvT7ZR0e20g)Kc~um7rSjpekOV*dio*eJp>>*ukGZv|NTAA;1^ZB4_MFxvd-;8 z*I4`6(RAH(EI@X>u;ubNe*2!=4`lqLvt)FU&?EC6Ww@a~#*HyvYwJtOj{-N0%D?3k zI)%eobhY~TD}Saufw>{BjZtdG3V5j33_CYCVMxnyffkj+&V6(09r7rL#Z#(u@Xpu` z-)THg3I?= GfX`LPhwt++o3 (Wm zzk6Qu3e_Q!EzuuPOaS)A?}%5c;qDv|>-u 6f=YUG5q&-2k|Xl6cEKNd z^ebn0dw+3{PAKMHbEEF?H-i?iOu0>+zS4+NDY3QNik$0))G?#CDT?HuvmkctmANna zk^dAPysM5n7u*b3?^$XZYKUPhS3$a%IbG2K)O6VAPhHi?CZk{fMfd+DQhgylCjf*K z!Sobqeg8Q+fbMk#A -epl8g>4}4)e%QyD7-2gi9ruW&--ZH2Y z(0}y~$_C$|nTY{G=xJ5&tvu3S+?;^R%l?q0@a)-p-k!06skx6z%$YvarCbq=gA|m_ z3q)c0 hQT4{u}1FtUdbEev?#~o$#qt`R{}4_0bTpR^X+mR}fx+zD?jI zre9m;;v_|Us`yN}{88Sxiw$8dp0_Rj#+N1tojW;VWmiS<&p+#I=mcWHJu$i0pnnG5 zSj9UNCojG9dg=VJE e&? zw3hVb5e_N%n6Pz*U&7OxpM9Bbv~p!Uwgi)HQ}Zj@i4$Q64_@TW1be-Qo;SUiu;19| zPZOZI?L4N`tiP}2pS#~!*c5;ph8Gxwm$(Ww0Z-VLmFg}5bre~1+3KoT6@Q3u9wWwQ z)0lDiFP0rcAjF%DJ%FOLClM`O+ZMQW)({_mzR6ii)LN>xk{2Ihh$QtSIl-c4i!a-2 zP)a^m{47DC)j7)wU!Lh)hgiL7db0q|k 2l3>zY8>UNt}b z)Fi=#)?u}KOtQx^17NUn%6}NW>rCXqPJ}{DxBL05vc2J-oX@l-FL|3sY;*{Oa#N5k zkJ3<0&e0ygjU%K+NUZ?e)@E&6)U_3Qzw}&)yQrjP@;B;&M-ZZ6DJqNB?9K}I3toc0 z3!$&rx<~tuZg=(8lICRbR7-zLBH+_}6<_6$91}uzRfLa~Y!cVCHh-k~EA#WaB3`6| zh(ek2kO|ngQNw=Fn*9;Q==Rr=hz_90_NiqZmwtz!MY5LGk^eX3aVqbX8*EFS-9bST z5oNB+wYJ19YdRBZ_Ka=YrwhC+YzvmQ%|}e0=-h2Iz8dA5OSY3PKf=yX{=r_bzOlU{ zVBu1KqhGxs6!NI`Cx5y3*`2vlY&013?v8)i)FXc^7}v8FhuLEOd>7zGG}Kn_iHGSm z^g7Z9BEKlC-z*Gw*tg18_CNGNzN p2mV!#r6w5O}4yFnfhM07AHc_`ghsHAcJLVoiAv$VgZP&Qr%Z)b(Tp z;RZZvyA?WkZ@{2w1Chexq#M*z{d$KV%~WU0TS$|8gmC?8``B~--L(+pd7wZ@e{USP zwR>$}BJ{OS8-FB>OJ;oUivKj{+j8$tvh_Q2tLlXzrWA9UnhEcCVIIO50jffH4ccMt z{wIA%f$$1mqxN_g4lsbaQa$D3!%8TqNb#V9tVC+rdPhkvQI@_N2EIt!`1l g JD|y(9vh^Dns#UlLm2?hsoH-jvDeMr^lsvfS=TCjMUu1DD(B) z1?kKOZh!r-n2WO(q2jGcxsPd+Y_?zXY^zQX{P 9V zgprSYrIYsB{!B^U9P!>M6Hi!UEk7){pMmhY{JO_|^k2^D4t%cqwAVZ!jNXoZ@{jDg zDeL8JO2;$pWlnWmdv5$PCY9JePE&KkLw^&-tA9(%F>mVe%|^yJ9majf!?Q->i|b`t zY-QR0FTUlqd;e&+LJi7&D=bGcc^MmtkAmCLKO`1BRfn*1rOL?%aze^lEAYXY*sptv z!JD+PI-wa7^x92XkzMNszDL*8w??h;I6ppK7qR^Iyf4h7-_Tn;|9 k zUuUA(e+=z~Ds}0N2OyuJqDgxnzWIw756lhvlcji8Fq~xb)k2k8tt`Wh?4xYm)xdwY z<@gt@o|bnzBiz_@4qj2$Y^y&`?;5$LEr0E^vtYaB9%^s0$m80-rg+4dvIwYQPiaMP z$5fE2l21zrf&H!eq(`V0$UN4_kmnfrquIaa3!hc_$P_x}Hl9=XooWAVk2#gDIb#!^ zwsB%Y2=9HQ;cBz-Jm#$e16c&lv8IG05S |#R(rW*UG4#FH=E>+~^yU z!&O8=gpL+soWomOSqpU=UZ>{Oy16K}jeUhU&LON8?(@mTdc?Xbk?->dwNgO*^?#>u zC&b3M`ees|Xq_uZ$6f;-onh~NFn@X?0SjXM22z2J_<@l!V~e9l(;4`%d!3>B>gZ~_ zwS^C@pKpl<8C5-kWOeeHXL!D-w)`kmu**5{aP}MUW)s5;wIE9qSzC{u?_PO2L^c4G zGzAxdKzX~xP3vWTs0Q!Y^uFNTn_nODy|4~+FBn`mcI X_d$zX?XH-D@C1_a7z z$_VVOEu8?5_t*Fd@|+_Y6Wv}kLFxav0# rM%~*b3m1YkWDS_U=o`*g zkmqKtsH==d7&9<8UoS`nc7EuJ6Z*znQI&`P@PPXt->>Sgx!}s-@oC0WY2edfZGT|J zN%86ZL-R?UV~ZZOC X$QpE%|e~G_d&Q&>u*rS8kDdMt7b^ieKBZcgaXdF zEeYpf@?^aM>K6m9-hW)7(yA!RCIL5Qnde}m?#f*lNr>n=_!Vd=VB$`CbU6z($GLqr z^fe|{6G6%_U`aIa$^%w@gk@nUY}$ M3w~V9&gfQoY8yA#K39!Lb+oP6hVg4U9HTb+IaTLp{Vt;{C6i?hJ08bcS!xdLw zYhXk^H)~#P!cLa0H;cek4v0kU{e@=|^qBDPE!)@3<*Id>u!z~4u0J3($~-Mv((sg( zs}dwz_$`)nw;b3hlmDy3;j_j>RNNQu2ozO?O?+=zf-B2*Kq_F}HjJ8879SIb7FE zNgWd1u#lL>fPcm+Q3$RQl$*4_-L1Ib4srWA#8;(aZ-RNMnnsj1rG*tvNMXe39nTmK zH5tg?FMo`I;?WSRM?KWk-7&F|5rxcMs-jJJt8Yn6G;n5~AfM{Wb nVuZ>ITT!EELLbfhAksFdMvu=z4F%j zIC*bK3xDvx=B|}!Jo?@)|L$0l5)h4OtYG#azc(1nwe6zw@5N@9>!2gFozUN3(F6S+ ziVUGSE^jS6@MyWC9>G=hR|0>wu>4`o62-7N_G3g-Ge@plFC+Owdn0-g-G5B%OqSG- z_!mFBax`#5Lc}KrD#DLpl#9iO46+=Vy{xiRdw &rnR)b4I{)NVSxBIwhO)9T zzm>UA`m_AqVKM^OH?rXfYtzHOH#w*8MI<|tzXI$D-HUYX#oKhRxACC?%8@1w!5?k1 zqok3nHl?j#sR_L)kD3w(S+*u)mO9BlMCmR(Mpdr)9V7PbAsYmFJ}3~fz8RzuJ@%fg z9DmF<`t)E9)wm2((E9fsy@S+0ohr>(&B93u@2nkme*@qVB@&1Q<9``rAUt2=q8CHT zmaig#e5^ZvVususEJzQ9mP%UJJG)jLf7g3pY!yiTS?*G`%+Jy_X-{->p(f34mI)dP z`nqiMP}6v{?>wjF@ko8E *~tpB^ivjav_J?W#G?UUE ;G$hdv3 p`DMnM)#CUt?94s6UoB9mRIR5=e(80b2Tpsd)-!c*x=nqkHn`H6t z+|k}R(_61UmWzAvra&Q4B~J@=34ctT^(LJ&%IvUdgQ0D6ZoDG>N7xhkTP}F~SYlOW z+ITZh;tW+-gnbPGGu9-{AJp@yG%3_+h)Zdv74eMo3^&&J0@hFeDOJqwqhdX=y3T-} zPN}as9|+0LAI@%(O*=GxV}JYH>eaEqUqA#-aF!fO9BS~PFY1^BN&Dy>IDa=}rq*C# z)5B*PFCCV`-{;Q{f@!(5-K`c~GzU71kH*7B0Op3UqwMLLpkdVvEn*56^fag@@f$ zlSg+&ED4X)d4>deb10CeAq~Q#$5z1b2FMEbVzl*0WR^8^Zo8>pj`+Eq Vb5$ zWF1icq{?JHz^^%D+iKK&Wq+Bcg#vM0<3G{eF*Wc7P^`a43aTRbxXq9f5j}56;q~)x zz5Q2?LKq`87ZoCtRGXB=zvWU<*#TF{U+@~1-ZDe4Es?MI+n`9;4$V<0ur%}m{)Ou4 zCxody;1U` #wrkK$lRskA<;TT6N;jCST15kS86fV#Fbvo5ci zTbM87Ym2>(1z|^ TShM0)8T&!}61Jmw&%aycC_GF(&@7Xs09m>Wnr;)u%5lAd#6>w(m8^;p9U##jEDD zWlvc^uuXLT?e>fM??y&@DsKLARCFnVROQnG$ZpE#ix;b{&N$zC)g4yY^)HNF>l2Q6 zs4Y57rv`JuKmX750|RrWbI=KOUQqj*tl-sG2AS1T_T#P>On*;VBc8mn<%M|)x8`(A zZl`PkZ=%tlWrw@ZrT)$LdtMP9Yav?nxyq?xd%+_VmR|aO6m^+bkB%s>Iq;_ThKJuf zrEsT19`sv5%ex(6Zgt8jjcIhJ;=gEGwAZWB=RTX(Q0DQLbe?G_6gimrX<(P)tY$GZ zaDSq|`jIOgK7Z;~2AOGrvQxiUBX(n+oaO~tOK)3qYN6hSKd4oIW;3a$>e5LwZsTa= z{dd@IxlgCBv#)4*U_r8}LGsg|@~hH}9piebly7wHh;Y-@Z<%%EhdT2nOlcY|9wzAD z6F0<*RgOdJV#TbVV=x)WJ%}~%9BZSUF)(_bVGMzdO@Cyf;TDRp*XdBEPMQ(BMo*+m z8nHw8yhV 1hKgxq_zSw^nPt &V;l>tqsie*A%k0zv4TfuOi7JRa;UHjJ%fSuRm>_J13h#4jJ#H3vj) zSOz*K&lo#bqF2DZ?-SL3oS@7TjF>~E?lr `O zm4BD3wU?*fP0;ptfvLH>D-q_R2I*J*F6i!4{mbLsq@f$Fiv9tkV_{mI+H2D$3}skO z0Nf^l;z(Qe>s6$?UZM2p%UwPaX0gBbW9sq1q!95GV7gQ@)nsZn`0GZy9dA|g&>j2m zWFgl341ry^DhSub0eWA6< 6`eGcm0fDx|b=S{!ALXc>CpN@?2{=>Adc+SdEZs1k z=)FhYs(8fDL^{@%AIdkSVhmc39e)s0fxfhI^tFdT#Z(}_{BB-~qPinthVmHuNWl!~ zXE;}Kmc1y40Bp2M=fBvzKU{sK+pNGS^5=r?6_iO4KMIQ0{n#vC#QRO HKeK~%$pjt+=YP(Gmz_@Y z3VlC|D3$x8lv%d&81G?s{>t-oj`b=$0Ep;9+)vCRj?hL~QEBRKZtKfq_@PrWZ#`Q| zOW4FvPN^Zw`EVgsWU~UrXTgY~LLth0zJ$f2S)3RnDfc1}tjgB$2wvDBQG9Myp+y%R ziq#h9O0X+6p(&`Ry04?UKY#g3>h}7*VEMQK`JAh-Jpmf`uz?=ofw*;Typ5vX0jCl0 z%c!#aPq(AnC#*9`@;ZBN>_59BILbu2_T2r28Bappu2gyZs~5h2yLZ4;2^veVC8_M^ zVnTU@Sxrugs#v=WqVb}udPfupao=HU*LQ1tk=X7j2V*dg09_xa$A9(lJz^VaB;~s= zOXpv|eresmqhJXl7hcsL>i0pBTjR%JU;Dv!s^9<^ANg wMt@-?p zUAcAshw}V=3*h!A@qge_Y)jQ5>(6?jIz4xxpqls0jZ8AuEA;?ST`0t;YTF@SQZ#~q zDuzBoMZ0vo$$IFBDF^IIxo)U;*2NVJMjPWKB3!o4OZ} KOI;z=0A)EKRSov7DB znet;H32H2*|3E4C#W4$gWuREfCZ*SzeuF7yfJ!;Y&fCnOwttFDEhlk*EUmWrY^2`H zpS9>FecHc**)GW?=slj{kHXGq=sEs;^_ycxgOYDF_sT9iW}(g$U5U#_KF%dN?An<7 zGeY|w*Fy2Wxy3+LvI 5H7TfCK8=G+iV}s_>u$$(CuFsjnAaQ{svD*4^ zF~Ib6QHLD8Qh!Zf{;R(~dHqy=w@BTb?M(1qQ_%0rl&?4>4)C6z2ad_rFO3o&VEVOJ zrsz{75m(4t9pD!>*T+Q?K} j5e(|MH3X7Pd z+4NcTZ1j%zUj7E04w`U3{pyXed|7nzt{FN?TO4{wYi^?SS)cQkQk-=1XsjboUOvx`^1;4fqgw9*5Pv*yz(jgX z`$nIs!GG(pET+FSEFvy~iIv>;UCn>=-3@|YM9f%?1=A?8bn2M$6rhn=kU;%CjTY)_ zRVU&7lKrW`yrVZ8cmC~JJg0C0-? &C;UyQ&mVcTPDZsbs{Eh7z@Zmh--$dx;M;;Gh zx#oR}W5fdcMGY$u!Fb_bw-tv?>x0}yzy9_4QBK9u#2-s#1>Ni}&o4$29lBq9b-;O} z7kc5kO|Oevc(wfHlf$ALH&W2X9*bLZ1D9_Lq{>^kF^wmgZ!c*s%6kVC1EKl4>t`x= zO@9ekM(d6@04K!cfemdeK&*UkOj=CHd84p^gfwl>MdEQ?4tB@;<>X|(3hLTYAnyr> zE`%;ow)QZb0V!`xiI(QNgb|H+oIC9v-b-+p7Y-APo%(%fNz@-|ID19gpvr4Ok<0h1 z=$!pqB$@kem=AqnRVqC#H`<)&8Sq~SSbxwrbY0=Y^Nuh38|OS}8GjRsXdur @TWq$^HqA*D0YJX~+&7 z>8bg|tvvl+ASbDF1NnZ$n9jaA5toA_J+B(L=ZbZ6W@$~G23zdpUBctB^i;Vf*FPm0 z@h92J*GH1!Km2fKliMbKra+L{bbrG;PnJ;MegShMDq?d8r+ O z_=C1q8tFc2ZzKZD^-Xpvb5FS6A|RKxyuw`-5(fIznFqgcLWe_u$WJT%98|0_6ybMv z7^UW^ib3Nq3;rh~h?O{&_yt81JXW@Mxr?q3Bzp`(7tO(9t|ZI#jR`8nQ_)gCtcx}v z(^`plh4ANyJ&$nE>!Nm9@_)vM@6u>M;=_x>r=P`&-eVc;i=P>;zH3)dl2K~BV;(nK znm^Zen3qd|ejO_^7OR@QldpI*XdxeEo~KWR3jEMJf-I0y;9k+^I+C7i{Wh(}R7LDK z }ZL&Y}XyLzPU^>45N)dv0uYYn(XnQzASZ#;P zR0sCo&xBl&^~@}_wbZ1F;v9Zi-eWoZ74$$L$9VWID=AJ#ydkMI$XoQW&HedE-)s{E z4>N^(5p@pFnfISaycr!$5E?5PeT@z|r%dpv$j$yl?>$sg)=Er|SgpTp`Wy7^DjMf7 zN*mvn|2+R5LDVtHWq(n|k_vIZdPJ^2oaNGqs5tk?;5KpY*mVMM2PO-zqnloM*CtOh za`;zNHmY9)mUGdKC~{uM@-j8lx4o^guCjANG<{PO{50}esX*OpqzV&60z(dQb!!&; zliRtFQLEV5sR=~Zi&(#Z>IuO#Z2(-=^MA5oe)xwRRQ6KxTz`QJLD@_YlgP8aq+cFZ z4!RY4Gd_MTINDuR $9#3B zICxw(-{0$`SAWflKZ7z>(poYf#t*--zq<`gwa{G$tsskf9nS%f^Z4N)lY2WBp7H{= z*G3ofwNk>!dF60&rtu-Ccl@74Bx!An*d>KF^^i*LNQK}pydldH%_8;%<&f23&if8{ zPv;Pr Lr{4Xuk*Mt`N-5p7y=w(M>7|IFcwikT5_ zaEN}6fZNuymq(vvao25+5sZyD ! zaKqV_xqthUrmyHGseV=b)7 C^j>(>)b*rm42Z@bF?CH0J2T@JTS< z0~+|gL((Y!*JPWRN>z96gR0JJ908M9Rd=Krwts`_t!RJxo% $}YJ&0sVKXR95A8B_u&IK6x)oIgV~3El`{U> zezcV`ezAi7gOxJbv4Yt;v9#Iue*WUL{z>Ym9|Ofj$>ndMlBed8m&@P1xg-ZA{`a(G zs(%q9mJ&QCT$KaS|7cf||4)03zET>s9Clsy8t?INUBi;eO2@~2^8zkRk_118A2Uf% zJDOx0?;f+E(z8_U_0K+Y#+}UBxb!G;SiSiu ah-1AFtvb0_=~#Q| z+B&{>9`Ke<65?j=9viC~8#`*9AZ&+iuzz|dzaX_`E<+G54aHqM8?A$H8WTlUjxc#Z zL dE2CF);OA1?}`r zZIn|XkAe&F*c0g}2N#0{nc!SeN?Q*dS1ar3F@eRc-j2%>OsY}p`!*D!kCH2d%BFRZ z1pS%bazTY&?mwYz^k2nmv fr~==E(hk$TifKMY zZ@-Tm(P957LG^3yB`dKP70O)@JKcOFmCQ{jnk*$ A(GZoR*H}x#i1J^-h)V8EjjY(LWsU63QTZwzK?@Qu@Q?hml#hQfI=m5| zlywcJ%n+lfz%t%i$W-j*6J5%!-&o;z9h&J|XB{2Q{?tv(JEYV83|MgZ_#x&pj)-gp zf(tVQU<^bga{1x@BYK@x?tj@Bg1aWT=&%u%>2i2)(@NM_BcEZyP?Lrl!t^P6$CI?3 z>TMUl+jJBIJ~_E0Iy@w#GDB$W4<~74Vch W;U#^vpr7TE1hbiFDO~P#drPjyYRq^kW(7c6E?M6n{}!w_c3;k-4ml zm?_{@h5pKAq785FbD;!r;doDfYgDRgYHU@IGdAGvW}85%)Q8doxdcV1kX{2NKK%QJ zyQ`c+8@o%~$PH89)-G?B u!)Fn(Qcwrq}*{u?sOls|TklRgFKgL*WO*W!a(Lk2ERBwOKSwm7Z& zS(UhyEjpa*I6lT7Ia6MrI%ys9MZo;CLJ`z9>!|5yi7Z9OM}L>obfhP5B}ver6yGCX z4#~}i*HebvYF4~gn6wQ`&(vF`!W+(yGupDh(@TbFTm2kQ-nw-gx_wD2Jm#CHRJ)Q! z*)#*!A3ODju3(3FsemRM0b4l4Vl01xy5LaJv1jXh$VLCUF0(fk483CKUEWKm+m0Iq z&M;)>Y??E?ntxNL_T64SipvSj_~l AYqZLmO~gaRmE5)h-)ibA) z IQCPdZ9rml_m1|uQ@sD5N$K>OW_H{9kIKv5}3r9ToGlA6^!@MSsc4u7| z*!t~8irTBj=Ao65eCaICq?^CycmKcABY(?aozQaw7tP_KED5!*B>nI-eOS^awPQQ@ z;qS`g%Q9uYk Am9P{m%z2D)XG3`dw G8g*57o$jB9%|K xq`2NUXidg4sFlm> zDK<-cxHmSTfA<@s=7}*2s>>#lpeqX8qzm1XO|hw?e)=vUp`4TKG;yzJTZ5U^$9BRp zi+_9 @;d=)9P?tcjrcLgb3XYX%?Rn(^9CXU0&?lk7zkLPPu`Mx%o$m~$56v1Ip zrf;^g@ooNgA^zt`d}0oQ-#^1Cjh+vq+qWE~(GTN2#@E A%$hY72r#Wx)4IN%%%}YV-&Ax-KNB?u zjCli;Z=ig7A14Jw=zQ=;EKEqK8-IZ0pTi5ev$T_f?AbRJT|5c=n+^ts3JI|nN*4 Pt#G`BJo0TSEM+D_f-GX z^Vo}$rgpBx**V(po*?6IU0)zI6+H(dIooxc%8=y`*Hdcb)t8_T-XkB`k$-l@O1uBF zlXCY~m)n_!|7SgUvnoSE9Bus8;&wXfHUQm=2O~fpuRNI#4`NtR;_izbyM6N3nCN@b zHYtTh9_5=t?4yG}CX&Sh(Qo|>Rg}DtzA3PLbH|c~+_RuWvA~Axn;m5H8XyzdHz4x{ zMCV1NckAI)vPG+(AdeG^see4+JgP-}wf!%T%#Q!M @ z<511OP-ut&WQfn_5V=^RaT7!8Lh5JC|MtxTSx8^;<*=e&C6fCwe0+T9WmofkW8hHF z6ezG_m_uo3 >GNrM{C6;{giXOJEl+W=cv$M;Ff@}Yte
|EoJ zy!tD>Hm4LN|6N{JIr2&|S35MMX9{R_|J;57@OW@vf}q-hW|s?7FP7v!72tPL&Vt)t zJ_!ajw7-AJ`0lB8<8M8qQ>?kL9B(F~?Qv^SDOcn X(~ )-B7r*G&i{u zbDNhohW9bg*ngqa56qo`qGDcE^}DpTx_M!F~s5x$PmWk9H_fv+Y=m37hI?ky{ z>`8&lczzSL?ZoEGAzt0}hZ3ib!!FE_(?{{$b)O-#J%2ZjZBnKHDYFyw$Oit8L+fsY zz}ykSf P!A!v1e%La?5Ez9J7#N&hSZns=l-LLD?;IV%yi>ei z#%R4?CLet|LD{jTCj<&plL6a%U|YVeuq}}>@R|I+EhZtbb?bVk%YS{@_RBjR%GwDA)#L`SB@FwyD4&&F z3IK+75b&agcd#KT_X=!Ds^VO7^t}Q?L_;%-@|kk^AI3{m!}m0-jCa69@<~A3K9~^N z(2^vfscnCj!8=O_&M%FD7zynj*pOZ60YO2`p-~({dPu)OE8NhiCL#T}SsqKY`!9sZ zt$$s~0YQ5j$4N(K>srdCPjUM~>|bsNXJ5JW<&LVcKrIV*!__Gh>%8*8Y8?d2L~}uH zsHFjtLGANG=Q#Eo;j_<0!C1eSFpE6vD*!ULKK)JSTBP)ok9ZJ8|H8I+_kM+K+D`V* ze?&?F)xTiwG6he6e&q!lWzHraH^SVd-hW_2UhwMMIyZbPb$o-hZ!l#xS@^9~_YJnc z!Q9#8$G1{Y!IQ7J(;(xsuP=2li&wYt{=U)K^#>vdcEkPE7v7VO-8&Ic_Ipt^uu?F1 z?kaWT>iT~l6-MP}g1>V>XuBD0#;*#)_wJw8EBs#2eu})x=oP$jv4Bm(SMQe%Xn!EK z^?jF(H$NM%cz5Z+8*t FO3V4)BA *RA7=*HOOigGC=!ZSL8(J#o=n|7Mhdq!UUfr^Pofy>RVC#x Le9fKQFeiNu6`(hzni?(S zP<;t=zvNFy1DWMLq3uMxrl(;gq b ;9td%|vl0d+_%-|T4~eMqhIO<)eGg_}L`d~Ch9$A3#G9HN|3 zOKG|ZkjzN%UciD>D{yq>An#P`zlrxd)iNAi20~p1f?WomV(R%wwyK?pU=Ep)^%zO@ zNlEppjQ2+;u%m6*(Gl$ETV(xNQayQ6eL+&aNmBiKQoUGGeV6rSb>U7m2-) 4ekPUg3aMuALhZcon7&H~y`9#=hVIqs)k zX~%4MFy+WYMKl}f4O7n?6%>Ye@vW8SJeo_jXLj@<)!S_j{widQ3x5}#yq>0Nib|6j zng;fD?4_({`0+;X@BURR@qe9F^^jsDVMp`$hM@L){jY56*9+})kvB>HvdI_I0Fzk|zO{>IY0yD{UQ)rQ<~ZRz#Gs;nY# z(z*0{iImwoWZzp8*?+->-TLc3h9 OMg~oWXWz=H!`rbop5Kz zg2gByJpKaSIO1XY9pfplnzWjtj9Sj_^^dQaqfjm+ld`^X9>Q!4YHoz FtWe@_S1KRkY36{ugYmP>d@7dErzxx`4 zKle>AW$B+rntu*2e&48xEcAk=Ap?)MY!RQFK5p9LJ~??mvA91ug%;LA8_|P*_k%HD z%c#KiO %IkrKSD^lm~T#@=D1}@5Jd(i2P`kuhEKtM?tdI-?Hr@RgwRcGH;-8YMNv)F zdY9&)H_8!#qQ`qdWC2sdgJ^CSR7M?m(=rv9ohNTf@UMU9&ZL=K_0?O}_m7i6FX=iu zkf>ezM}*-YrrX`F3wCz>hDRUWF5&Y6QRo4^qr+~OsCj`O=nG{=Mj_@8>Ny3ERO0OS zv%?ch9Di5n6M-bt%64RrQ;or0(b)jAeL40gp &Y(3*~EvlJYKI3uv zU1`nh0S6Oqv{v WS5N z-2A!F<9SxMFU)zX$n-7!3f2OZI6VqF0+ss$twZjbWU3B53MvAvh^l81Y3-Z4E&{Fe zl7FgalSSawPv60-=ayvz6Z28oLVhRQUNg2wy~=nK^LK~b=+m~ueQG>UJYj`H(7AWP z76>r=55P%MAf`ZYPQMx&%pMh3yIIcr)D&9y8;VOp2|Q){4sN>RoWr&e>Q#n_+-9>K za2uPKkxY2Lbtk$>gQ4o*r@$_7h)y4bAb)U(M*mDoPew}ryk!NK_c0<(!i|eiHL7P+ zT_863Ygz>9!^BUxAiA0136v}%RBna0(TyH(mzde`Oe9)01*|;USb8G1#UL%mT|MqXc@80yC^u67FyxKske7dVkF) zm1qDn9om-~ljAgixelXCzDZ`9^XU%FOVvq7THVDCwvYuLKsAY(7j=!x2fGZuS$FjO z2vV1*epa_X_!up{Tiybz<~1$((BDd(&NCNOWWxu(b=(Dz1c>ks(v)veg3_oM@MRK- z=TmwuR???Ma80TNHYt16V~vmI$A97Y x*8R%m}D zB0SB_P4V*e|NeJ4=}IDlw;|vzZ=ivsK|>>O0zb;w +Z@e2 z?q?!YBZ4eK38kG>N+fywF54Vw&4WKzF!)r;hK3Y00OckHO}G{8sHqne7K;F-{7l6C z>ek9c*gyDrH)ij`5cvWGqmD_wzE&R;G?H!%?h6J#Ur9UOcWnm#!89!r3rv4}fQlaV z {gSx+^l zy1;_|5<%VUeUCSPz+5@&{keaPrCbYAB!!MRyp*n-Wp6$3L+h36F=R8`HbXMp )l+;p?icZ6 zPgxq~x<+Pz1Guk&)TpKbIe~iiq$LXV<4Er7GNt2c<{k^m%dZOJN4J0f5i=CeHRWjO z2iF`;x3H{f-+K?%h1o%F(%aMW*E8Z4vw`jR4ftSADsV5UZ*S0j&+4K%Q+t^eHonZ< z*iY$bF>CCo&VX}KD}6UpPYyx5MF!Qy0kqZ$P2ZvRJRX~oxOHNl`&F~eIPTDyV{L?6 zsxZ0g%@~QPnk4V*XWf5tHTIgu9ORP37~>yU{9g9UgYh-Ycw1KeNdv1dR8c0Hk}b#Z zr^?E>cM{E<2diV&K<2BfPY$ZWKZy~F1NSq1_wR%cYbu0)%W}GW5pow?|7b7pd?p|c z3{P?#_s9uh^Mjyn2hcUHPh1n4znZlC&)LPQ#h}XSfYx<@FdTnW#NizzjR3K|b(~*! zim*rm0gAdop@j)NXyf|Cldbla7~#LXXIGrv XDRV1A)#ck2`E)H*; zT#dA9_eRSI=vg16aR{R4UU7mltJM=XJ$j}cs6`y>38~YXzQ`+-EAwAyP|0uJV_;n$ zrDtR1OAPjT9(sTCJcPk3GF4_)-z9PnEcmw~cK9fwy%b>uu`uPmMfZ97oC?OV*c8Qi z<{i>4kloXY7)CkSdVgM2ovhvc2O7H*cV=BzKaqOZTCO)Y;X7rK3hIa3UzO~Qy%A0= z^)C|qWj2vJ#_4;6HV+NC2>(}kGsH^WUDrVX-?L;bK=6NXa{?xqR9+wHWJ}a2sN=x= zVYnUMYd5F{Pav#V(-fo=auJyDnH)K49_fF*Eg6J(@^WR4BaKA75ZoN)?Mi!&4_w23 zKrAvu8*Mr?C7#Jg9e42tfi^IT1OAcW5(P&sxeJ~bG}^~`Ie$NDPaa8nrynx$a7|AM zPuk_> i4783WC$l=UV?*6yscvcbL$tx%j zj0TbTYICfKPx)^SuA(F~6mv??Bs_N*Qx9z`p{;+f-;PQ#V6)TxgPK-g*mGH$I1tYN zu-K9ItPU+=NGT$eZ(x|Ai#nw+8m!DF^llk 5#Ik2b?>8jKw9ZW5E^#?x(&&1hw6g&2jpyO?vSPx z7TF6l;CnNrbLkFcm87|;OpWNsyx%rf;M2EKrB4O&p${$Ah9PWWL@!&nExvTURR;ub zu8!?f-KAY2opL(T>uSr-?p;_z#Z@;48D)R$r;p%YA;W_h!ms(o-9BgMIX>X;o)bvo zr%BsWU`h6_7Q1IAZ^Xy2T5EOQn^8_(lg X_NqASOkL|Q@-c)=v zg%XJOZczJ?r9u0NsqtbgZl&G~MOJ$fFN`Yk2j-Ss6-RAr%=u6Ix(2E;$|+AOvYvkk ztd^5rFdGyaDCqc{fw$r|yxwklyN90l&gped8n6?%+&x#@QVV5KWHR>2cWA4u(YS78 zGBv1w{EOHx>O5dL63(}M!^co^Dt^|#m;Drw3phqN)nq5KYcokJ(|`6hP5S;OdwFeW z^kS{%S%`{`3Ws}9l#|Uh`eD?-)h2)2|4^aQ>Sk%!HKg9etyx+Nkou>{`s{t4i;w2- z(CU7Ue*1s9Q({&6hg?6aov1}v%0U^H$69Tx6E>{+lsqJ7j@N&mW@KgI=#eD$US4K@ zF6ba;lZ*sfeu5^3<+|;z?jG<^1TU04#c4Yh@^(lWQD>yZ+ zolXVDtO64sQCU?p-^CQl{S^Lk(Heysp>MOgNQDZAUM2^jE@X$ulRpIFa`q_5_ThXA zX4?MFyW9f@o=Kx^%krB}RcE!K_76NBN&Zi5S#yxWH!0F_>#T;IuIL>jpDx=MBT|AQ zfoW@Z66g|ugU9`nEPJObqWFLDWy%GKs&u<$b4qT|j1r>gCPhgE0Zgk&SGevCiV#ko z{o+URmQ0{LWc#Mm!rm<^Ct_5(Fpl=}8(FLel_RPb8NmeJ Fj6*wyE63ru5%nTuc z?GtCu&mF%DguNw;;iAd5AnL4vu+&N{j*msp4@saI_nvMpL81`9YTbVgo~nkcStHLS z_k8->YTW)kB)YMoJOAe9Uwl~thTTk~ET(8&9}duwXS_%^5BS&(1FwAAa(lI>Glm8* zsTL~BP~E *wqAz*}rSQwzwU8Ia93Q3$XXtjDK>xYRZ#Ly0dxNN5u|8QV4et>emjm&O6Xc9lr zJeDujzL$r@xx=(Xj!SlO?PNZiN2H`v@8FeM1PpPWC3=6}65oKHX^TNZJ{tdKbSXAi zUFXH{VP^^t6j$LesLg{iwgBx!Eu-I4d>LP}$uSmOnIKJHmmH=U`9N;HLHEKiWki-^ zr1X+lRIDJ@tLK0L)MeY$w(Vfui5qu&(R*>R%~Fb0PyoHvu>e;3ors;8xU2(y`MG3x zY!A(IEo^@lvYkhCP3cGyD4vt^^{idqVpvfvz5#LnAj!r }urYaPGV>t7t(zr^Vh>B;H-BdEOK}R%8D0E|zy*y8DUT z@Njy|liFt+y8b?Lim#J}UYBz-UDq3Q7@1Xjn*D!fxbGVy@@;<)UZ!&{e(BuN!^bpG zCS_anO>9Ty& qcMfes~sbA0_xBKrG?B3z3f)Ot{ED{br6z z7(`9gK3t!~nxU*A{$2MM+b}>3uk{5x5b3|&mB!?Z9eo|}pHs&)|J~PoSrK?i>V*26 zs3m`}c~|Cz7I~8RnWlq*tPO|km*A@gk|f#*B#O*d9vQ2HY8-b;O8@3;{_7 I8J57l-zsN# zyS9ui{LXC4W4TM4dizdb8=ZX0xq=F0f8KwHV(4{M54c0T@NyDGcsuskGEj!)Y*&3o z1Vma^-3C^^{D)#WWfgSnDYzk5!Kr187B^9=+3f1PlvBDzymF!jR|TiX53PD5bVe%g z*1%c$0&DDDH(cZF@CQg&B&;m;EI?7-Jv^~Y??;34S`^B)(59_>((Nq~wxma%>Fj?G z)9~vgY1y_Me77XFk?8GKa1PTIsF^xbZMo~zkGqPZ^v?u6Sj!LuoDHRGNPThZz8{`> z#W4I*9U{VAWl^X4eRL5XcAAa-AI0!x(`i+eHhrDTsYU2baaeskhq^eo%hrO?&);uL z)m;EYC7GRBuNgU|O&Cm`X(;||v@3soMT~|fqL<{0u^$WBNy2C3t!{So{DUM>)+R(o z4889D=Up&_?D~3Ve$GG9m;Ea@Rlv~|Qm3OT&HC?Y%~Q>%Z~va~%gOcUhoQZ1uJsLW zPY4#|G^m76Zb=s=-NE`e!m($s2?3w7_v^JCgBsWDBVfF~Oh3|1BPZ-X^?`rPHx_@u ziJ)(B0E)f&G!NrAL9c?C??Sq?a?O~R$v8HmE~L48sV*{4qn#E8FbxvFo1hXs-@6Jl zbHW~qZ(}c>$6`ri*cbZ8NVH+lfV)$%Q=Hn$p6qwN_n0GJ>!Gf@;G3I{t`=)HZdc|b zBn{L?W;rlt(I1X`{F?0Kw@H8FY7?`s92rM;1QE30Djv=|EVy+#7&J9WYUpFv2Fz^! zY5(u#% gyD?@9}Vk6wA?fLcIieHX;rKs=b{0D%}1EmPm30ZA1waq }HTeNSoJA)|_42PDdj7Cnbo@KppPa JWwCJ z^(ARo_exQ^L6&giW_N!+wA)|FqP e4|Jr5V$KA_w~NgOG8{GEj8 zqE#gU4_fQ>EC(nGA80oO_~~-#>trrHl YC^5Xr8>_tC?0hXqVX< z8@p4MZN1#4-fw^J`xHXbaS65QR%KU>{`M=~wb-{3@#&gf1y*s5^@(CXM%kuA5lyRH zOMj9(ln`D;Bc6Y9>r`GY2QaCK$6ScyvL5Gu^~n@L&rJV1BfC Pi*~M_9L>fRqD0ec5|zWC$5bfufT|G0{?O1UY|m3z_~r;8W>IQK8nXu?}6^ z`>rn4N^x2-c{1N#n`i{jijnZ-1AM#9VX ILV{5ab2>uJTg^hg*h<5^Zy*=I+ z+ly&4AN3uJY8Bj_i2WIi1xdbt>s5M6b-32|wyUm9aNm?}N`Jspe==o%EljPaq8mMR zxZ1#aPriRF&`UrP*z+{J``7%{|C){oZ5jpI{1*CNzRRB80n6)_x%WyY{NY1&O(s9W zN~sk^BYI|7tx`@-f3KfY*>H*Qu%SIA?h`Y7MMXrO%1X^H|2mL3Np*QnC;itJ?sC%w z3%Ee;-OTVkvZTGDno}|-$P3ITg+x@qK9y@1$R&T=SKhELK;Q=|!VbbG2bKY|sa=#d zQvgf=RZwb}{D)24!!7_It-&X@p5YvNcWwRt^(G6$(N{cw&X@kmHSfm4--fRK!8k a;X zgTQ|hsP+N5dRdhXIO8^Nnqi?Ip;>W}E^_8#>>@TVU*sL4)q#8e{>%63%FN!y^o6p; zSh#$ba6R@X0t2TYW~xdlD+=&XZCCHiolJ)9`??=3`gN}lu>qjGO!9SAeI4}x7iRr0 zHOu5x?f6xwYvsG=GuFb7MUP4 {I`eQ(KLTW&k8DT|A~#^Duk(=dtJ^frm__dm>)ji?Dw` z9_}=EJa$aW;rHr;ia{gC&NKNVlJci!I6 G`y;M^effHvh^lFg)%QZ`RV` z2-D|1JH&*#Y~}8k^EuATHFSS0PZh_p3YN`y9(c(?W^%A@sK9|5d-1D2j s?_r(RtCn?Se)YlJ&*Z?gN3B7;7oR<^M@1Fbw z6M2sS{=c!Q$^XTE9=*a@sElP_*mIO+gJsh}yvDcbQnMFaG4qr*Mfho_)2^@A*PUB~ znTtj4 A8ALA0`q-NK{t#a1+$3E$1+P;=u&%4Ndll}&_obdS3o;!OVknzT| z$0@8k=RCjk0Wlo7eCmJvyqLV_Ti?CXQ#5U<{1yn&% fHw4%hmB3!+LleY`Tvb G_dcljrNwfn2o|< &>!Ro^~f&B0p9cR5>Pn+93W&^g_iD;dKAa@B3Uj z;E{)%SKIIAf}4NK8XNCp{dKI%pyP5{G=< (ES??-@yUd{%)RVGbXxr|QwV%n)N;9Ex% zpEs$pb;ddSLK@r4+G;)dOrfhE={9E`rr`0IT}I)Tv-5w`)O`UJ;S7YRXFhKlO^dcx zX*a$yf=StH?V8CJ>pqg6d$nZzB5wRtqmy)g2QP*0iA-(m+({g{)v^$Ze D*ZGT-uVK@3beDsoyqN-Bnm=|A(3|Kz9CAi-yzBYV|t7>@oQSv11h z9Dk@-Zs-jrzoPnAYejCAYh)LufjL28)~vCtUmP6ma1VO}Up$7)Y}8rwLZ!dSL%9Z9 z1=@cs9{ol7(A~rmt!S)3zOD&}%<9Q=vs%zSuwK!`YQqh=6%nAVyAO-n^>^qw=~C%# z;9ep{7qZPetmhOmiWUElM6ugoka3t$s5IrW^v>hP l&$7 zCeOo$jdvDHVHo)KW(8^9=x}jGqy }$FPQm_}N%Y_O*^W`U;QFF5cZP{kn&e&!fEQMHkGz4@ba_*$rNfv_3E2KUPiU<^l z#rv~e5zX=HveSUYPFF?d;15)-MzAz1rRqcOX7boHE5$JbE6yI1!%zlMYJd)elovxZ zO0oLev%F&W49&}k5$OX}zRZvHUIBmo*p^S=;BxUtpXy*}Qsr9^e)6C=%BgcXpD(^9 z-4sLFyl2+5=F|QY_Bp-sYG)(^SR6J05clJn9dPy2pSJ<;F;!^&hz_!sQ;_Aan0<5z zOxWZ0R4;Hz=$&+7uT4458~3Vj lb_Ot$DYW{B@|Yt(Q$utW2VNy zbBMsh2z|pQ%wpIjFFc(N%Sb0r*hi4h?c*GDHdGrUPW)#^f9pD+Ho~18;N8=CC>7?e zx_YLHry}o(7E%@RfoY+xIp;i8@#s^fF7vvZNQc)dZxMTO9S-~Z8(Zm7;2Q~dxsvlC zF{#8;chU8J#vB! nT`)DuaBDg5_9v~y&%don;(}Kx zg{v_wg@v;EY9!&-l -t|Ag39`6+)4~sk6>NzCgqQE zlDwJnX~6% C%cN!UR|H`~O7(^jq$TzP2vmjh1kY%cK4DQ~LOASAFJ YTf8%4B%6z1hb^N&yu%PI4u)b zPJilfRbnn>!F$2eWLLeYs*#e^vD(I>_}=uKP-ciNB>mmWE*IATr=__2?ibhf@5|+t z#_H=SJAwI$CpIAD53Uc3+@CNt9}8i;`@|hLYHPgPHLQOHLU2sR@DPS270b2FZu?LV zT)aa${qS$u^+1KUp4?l4UxhPRp1nU1&2uNmiVh0v-VmAp=wq=tdwePz>O*2AwG?^W zcJ?qN8 @ubZX`Rfj~{JN?t73` z>ikit{*r&v&;RYH!C|acU_~zQ^IY>*2srWB(JV5nG;EotmSZE=(zm_~=Ta#+>T@O9 z3xp>r;RU9lmId{x*P>lAzU$8iunVuq3w)E8opM9%+M(F_;twAh_41dsUcMAak6slL zeqXpfI9U4tUU;0ih?xB-UDrkIXuLe)pr6#NNwR;WgZnm=cl1V=0$N_eoX;G@%eh|N zuUCVnG~;i4^4gJ3LVMAr(Y1@O9r1g-@+&i6JyPTIT1-K1%Ez@O)w_;pJ#W2rTz>-O z&pwu6M99Js$pNQ7u!3-f#oo8B+IS( !YjbEiGS AD zF7JE$@ao8pDYbQ ?hiYmzX#M(DQMtG@J0$Y1w`1f`0sz|$+q=PF@@s!8=4DPOENmPJ4I4|Uc-OG z!9MMmABNu?PVWvzJxFNTehcFj-pI7_wY!y3j@;UiaVPcO#m@gi7hs_uFnJfdrM-)w zbl{{~Eg*LvVt&q8>v7D$->dh;SBZ785PE-bSUsXvcC9ho+{1b(QJWxexqQdk%j<5_ zSs}KD3yzH|o>zsC9p9~c2=b_HYg~WcOL%&V`#pb*Qw@W| z<@)UT^Mt4M+Zi2stF{jOES20hyWByDn>-r`JY7AwiSLkC*MiUSca_rE!X;TCgyKqN zu2Tnb&F7lSCR`XaUfgz7AQyEHU1op*5a{ ~Gc$A_%K{0~a`(tBxR>2@w;$Ps6Bgh2k^zhS z|9Jd7--yVJv@ew{7dSDl3N;JIfwvLtdWUzXuMIB0?7J9^yogH{(1cimh{= zuC-L?iC%JQzd+RfLdA>y>mU(e;L*yS^w%8|x4>BX9oom-bn(klQk|YHy7*g* r~gi3j74=l*pSgPqYihA$}CfeVMJ~#j>>jpAtB )+(B=T-YeC^m#f^EQ4ir XM}z2Mb9B>TnE3c683}UBLDVV>FZLB8O*ev# pHXiw?^In?mzyR8k*w!uXQ;{Ie7K|e&~7Jd+nWi!Ei(8P12D6qHihQ`)Tuq z9%BHxM)#8R Z%o0CL1G>Eb)iS{O!wpnxirpMLo?4A|jGc_-!$HVAOrE zrQC{p)*btMN0*#y6GP{RIDZ*A&yAkhk)T^V$6@>L6Vu4*gelDgd*4wE%J-V(|8M2f zGzR!^Y@QVJ%qug*XQ>ZZ5?W~}xX>yK`o{h%WOaY@lI}bmEZ3Gp3HV;}-r5J={9}O0 z&gO0%A3HO&kg4x;m37)*OD{@#N-eX#BV@%H#UYCkVCM|=2_=hNpk$6fIfx7+(T~NG zbc1v_^HX*r2LdI6Cfx4;KOfvxFgYAk?m@mNP73+$EhEVE#8v#`Tzn}KFRFdw>9++R z3iy9F5rRoXpYb~gyx6}n?NjN{?GsIV7NozU-A}En9m>{@_IV_ea%W{F%n!xU1oM{q zCX2#mT0>Xh5O$Rdi$}&5+uJv$p66q_jVn9D<4NpqXCIvBe;mWxcI=OgaKBaI%3o~< z?(=rcy_L_*FuXdr?&qgnr^u;&mET5cLSlbQLy!j9TA8H&t_U2Y1p=vnK*C0Ck@mts zQ>_F63Li<@)*JaTv`l>~(3TLx!d1n#=NB)PLFE*$3scIX3a?&byQ-M@WO>nI!s~jK zqO{U?x-@PvL`GK<=75gvXPcdJSWyoF)KXIf?~2b=cK)b%#SU<8|Gu&BNga0ZfA4?E zXx+fus6J}kBukbM#Ht`aG3!T~aPr?qMywwj8$P@mgm7gvG)QIeh)CBlm-nPnwE~}? z^fbl3s0~$_`Qt;d0Np45XwsEA#c;`457xqpyJjW-Iry=7; !PYGEskM1SekV^B5;A{@sKzD`VFac*NSFr(!6PrmFGT(%zkn)!B?&MG zS1r`jQOcbRmTk)xOPX1E8^_AzP?YcL{T45*Df1`S*=8brgW-%dwNMQxRy-}{O4mp} zTDZec;K)QzX2F6kAtxXcQ`q$(HfbIk;N^A%F)WKL(=z+-)pP_G{Z|$MZ-Ref -HRT3 z=Ykj4p*HgD^fK54-Ik*rfL_;_#Zm$0jW-2@`}DlJCb)cn}^S7ODs1UGjBe)0q!l zfm7T!QwG9GDEJYrd~6Ksq|JYDd%{ueC Uwovww27i_bFjsp7ss)Phek zK_u*ZF*dXa8)^=^ok=#?;Lp12WJ9%E7#A *K-9H#&;l*Ghjv8hHl1vEsko z`5-U ndwMNW1f%gZ_85(PQ=%CA7og**g-_ z{^<}B?H;#{X`9uO(oCF{=Q l1^W$66j5@0>K0 zkdqQI2AwO-P08JWhDU#oAT>C1Ujy{z@ReVe-M?9(IdF0_yn_5qe3=g92yJOEaD|ng z>ybNCx-NTV`#GmCe|#$ABWSF1+En^AvLkNkIO%wW*4pT*D~wL>Rix4jt0#*HlHZwP zW-r2Ovt{Cv3{RV+qXS}Bnk+N wn*UB_h_E(DV z-Hiid7+hqIh~d_SEV{N z)S3t$bg2B4Z&m%v*$oQ47Th|zF*6EW7mmu8SHpT^VK(QPx80cJ^UO2H@Xub}o{48d z&0H>gyi$KEnBsCJ{$+)Iaz$Ut(Xb@8AJ@+Y2nyv0?-cea6rCuo!*p2Qjc7_H5`Rtg z)Pnga0kd0BRa+W# ^#Wtulxf;N4)lkPX=VcINyMB&LiOF6)$ci{A5vp8)6O zUsD$}+leHHl{%K}N} C> zNeY~~@Cpfk;?sV_jVZ$kp9?N>d>8VzV2N4BmyE9upVqejnV{)C!;jGuS)>cnE-~7a z*>R^rgWRL>xi6c}dkVfv0@@|sPn(gDM0U2G!OckNSGl*((;C6N>G-$17tXeO(szU;A@9L9r8}|u8Ir#3BSJ#gfG?8<=1B8KU&*3q2Dj! z7@h_Hvc>g~fuVi3_+abXE-|gEVA Bp7COs>WzHB*Jqsui*f(MGVXga#DQ_eem4U7m
N+6i%;1}sE zOq4wtd(n?GX!SiNbP8KSSi2ttO9m^28#bK%z#b;a_)Q%E-MrzScfaP&zSfy?V0wS2 z%E?koa204janS+KZaK4~g&tDoo#m?|_d=K$VtqPNPlvgo$YOxJ1uNEA{e}bDz@3*8 zv$)zQrv)jw0Sqy*4JQNadYz2V|G+=)SiC>)Hd#QGeE?;;&!hN{f^gJ@Ptz|05EgLZ zHNo!?%pNG~2`GYApQ%)L$rdSh&SHN~XkfKZ@Qr2Imw_PT`vRxMTA0H{LI8bJIAH{i zTxe&Azlnj-nh|nfp6qkmbCn-;xG`^Um=yv!WZK7ni6Pova=&NA =~@*9<@+~xkBr{IPHigpe(j|{`96R5ES|4~ zxhwY9?IXX-W 2W5_CkC)WzV10e)+wV0|?!DQ-4OQliH{b>4 zO2fLYKPG@a|Kw;IJn~HB0EK@UZig| zo8O&^z#+unP|-K6^HfL`Iftx13VuRqgI z2CpuXe33%v@K%;ZkwR8!qF}KSoHa9B-(&$|Vv*Vv1{PPF# pTn3;0}K@lCFYn%S&a>QuEmz{h{=bik6|Bz?Yw zDTu6E>U4=Q(zcS}tK_Am861l-mUNQgI{?BI?%^e0v7)bN87k6w?)MRg#gQ9_m;cDy zq=2H%m|r;NH=wGnyBjy3fvNs&7ab9qq*eXZ(7X NJvcu6|!IGxK}=01NhO?3L%$%6JdXglYrfkyIE+@HHbfUnSV@cPzCf_&b^ zRovY4fv3?w*0N3dPxqa0Po?NFWw))n38tWP`-f*uqW8X4A7Fo(;L=>574*ctss2{O zb5pG?dLX)(fbI67TWq(P5F&ZHSy&5#pTwVBg;=XTHEA`AaKY`keKaq4+@V>;MYYnK zMqs@pEB*9o7U@yThq#{fBer_R`hK(V3$J5d8SOz=bgj&<_Bxpf4oU4s!hrGUtsxG$ z&yq}SCnWHRVN!qF1XGT0kiur#G-NmMTFYP_Q@JGV|8RA)S}gy^QTVu8Woec+U^_!| zcPEw^5-PTuu$Mm`>ZEp?e(~{ESnHwNgydS77yWew?Inthl`wX3G%c&VLmqM9QT8 zOm4yJ<5Cal@L 7EPL? z7tY(}Tehin`J~4SZyzbv^UvU@*Qv;D=ixO|47}!FDuasEyBOCgna*(1TSby}k1#sv z)yv8*q>ao*;l p?kP4CKh6j!v<~p+?d1~h38jVd ze0dFc@P2=hnNLLjrVl5%zw6|2{M``}1n5Y91${58-G69@gLjla-AP-plyf?!GT+~X z&_{vS6Rm_9tPvr$+PQGQ1#cz a^!yMidb9RVXD(#)hEkwe=N6T-*c zJgdS_7Nk2sc|Jh#T-XFxEaGQvtY`I+guxWk=_3`Kih#610<){Fxo0gSkqP3A5~;j> zx0y{>ZtY;x)51n9?+>Ilt@*w{>90@iO{PJ*6$S!>WhQ0Ud33D=4>P2Lj#YlUbe)Ru zh&(7rU$GxB @@iR9tRz^ieMTIr5C9vZ8e(AxB3r$XgT{Q-n1dUUj2D zTMou^AZZ9wIoesP2*!r(Ku{Anhjikm(Sll6>Meg(lzr1J;5ZELu>eaeYANo3zM6>W zgsj+vRC`_bfQn(LL4dRdM?r+oUcv2A!Ob0`c;U97g}G_&mC1Q9d~&sI8?;I9bNM6u z`Mi4Xuj+HzJrx5~WG6IX8mNWJa{w{~8 z%H?P1j&6Rb3IEYsZBTBem-SGdiq+OOUDWe$)??^ho$T9-@GcC6@6fdg> z?+whpw*9%oV%Hp}mMUCFW%#1*i|fv_+I9m5e>wOH(vlef02q@1022TJ0BvD(Y++(A zWN%}2ZDnqBE_iKh ji-<1jvuZd$Z_P|;=c>_ z=OkwToTaw`CD*%GPVj045Th%PzJK|se|pdUq~E{%pNsv2z4N^bH*k`~qZ9J}c<+=Z zS&)*K1P} +Oby8E0AT653xU6QPm>fltVKiw5J$l 2(D|gF-6;?`hi9ek%f}S=hvab_5RmWDz*GXEdO0 zN<9UbO%DR>!2(82Mi)VpB0CO1e{>I`>#*ooTQ{14=<1j6 BXJTRXzl zbfW-O$)aN~_N8j=%rN$12I>olvNSF=zm0B}^FW%Icc-<~_;pgRC;l`+#r97 Aca`$-fg zOkKMv7%xk4I664puj(kAwCYGQi>^;UymcwQ_dPIW;~3CIq9*$@>VAA3-RJ<7?>Nz% z(J(nkXJBz=QQ%d)=?3O??1b*jq^z1rLPIaNgblVW_OG0j*2WFGnx&&8jWai`9)>g> zX 0Nv5kR>g9nc}k zZIaSC!7?8c0ZxHK=BHqn@kc*ze(i-)Y +@ zSD>)B2T%;aRaHcoB~|6`DjDa|72VI`7~G@t=!9W^9Jvm@LxPGJ2tR<8@kxYCn$omC zbtix{{PwYGPojWQfAJUJOJ~Tw97zAMQ~{s=Nd4(7 ye=c;jg(#lKI^_fvq>Igs z0a@SNxNN9~Lcs)Lbd!^^Zf rm46C^&+eRDVQe`k7eSWh;< ztoeZl<9t9ie^vd0Rex=*3jA&cgC7t4pwtQke3#@$CcHIF5fvGPL_?55HWpP1`V*Ct z3Nla#5s?k@FpNSl?(+;L6k5W>QIr-MO0-^FpFoP=N8x%2N7kq1N5kpDpfj|J?*p=> zXA#4u^a~7?Klz{aZ5JfSiw$Q^GHUC1g>~ReQAg+Wf9f0hCX^ncFUU7gxFgL~B@!dy z2PMLxGY2Yv%6|>=Rz5eNq7z5cbKNs*@tI^nFaifMyo>N00T6;f!2gcsbP4%ELXYkw zL^6a9lGIFt3j1Z{r~?1rD@E6SI`czD{)OYmcaf!E7$}TVtRtwunk?B+qUyu45+ybA zmy#>Wf6v~kzTM5T*ol_e uwGP5$ z3l9)KiKFQWV0V@}X_8MT|CFYW6Y{5@1ku!Yf1QA7(=rODYGLI8qfi}w6MlY2HdPvE zA(Rac-_az&NhGw{vFoY=+sgzg(J@H{0 OETZidQVWl&k?e=8@Ou zF&XHEk}=JVvM^n1FY%(aBh5Yg8CPMTU)^yd!$)mpR5BL>v1)$b30)eT(%&+eff`Iq ze-Y-Lx(kdN=5lZH%ZfQORxy-tgD9b*IJHm5?WKE4!}Bs8TrEqe!NvQEjYyMx&rhZq zo63WrQrCAtr8<(s11#_p7OC#**awOP2s0kdotse<`%^!30!?gI&-tQaG2)ExE5PPJ zuF| kZHdgMNg+fHGd@(th4vQ@E5#3oan$wTZNN zfu9=@^zq*7!{gDLy%X{+*%Bcak e+!oTg3sw}}qb9iq{Z_TA zD)tgJKxbt|qxkVX_{(6uymGP6f5KT<1?wN-!bjN)-DqOmSz6i|W%UZ1A>Ah03_)Ar zE9l7iU#tyt9D}E8&Hvh4`d0{|yqfI7|Gh!;5Co+($|C}Ko0km^tH>?0<9wHh6W@py zcm`&c#M{Ati7r7Lq9!=qj}*7f3ewMmEkcUqP!{U>p?6UQb&{WH#`g(VYH@!Mf}Pvy~dKb z )K7 kp9UC)s%H8KeVwJd)pLD(Ujzr>s}dYoO-MiF!ju>VFrf>?=)Da+n7+ny(1R(} z`#R{NhS7C%a>!83f~uQ@Ne>e793J!=d;kR=U$&eS6hBoq$s-g~cce#ZB|f98`u^gZ zZi7 ar|I&AfqZyW@i`wHAtnhArqQY-q4&@XAI$ 0ay@;&lk4MQ2dSyMvi@Kaxw+(TP)D{&x3vbzAqYVEy#8_0#q0(KY zSRI+smH6rdxYbZM+ENRH$jy>CNhu>kO~a?q?EQEK1D{e`v*qOV!fY5UnpNveLq> zxCb=#(bA>;NIie9oIq@SwQ{ssqGCuXrbeZOZN~&tRIFo4vPANqu|s9uSLBm!iC5XE zl0VjNz7Sq1+Zn{S#Wn%;A%HB9(?{`{%DRiP!K$#qeakz2pSxq3Cmt~#liN@pdb zoMWC2L@rUCe`cQKk3U-L)Kgn+?-ab27zipHt?=t&r4>bcQP{H_v@LKZ6B$r*qM!$I z0oM*F@#2A;EH^sp+Qs+~wnhv@6VGq^$X_+@4zdv4s(n3stJlrqt1Zr!%JyeYIHlf^ z8y3@4jdr!xS49B+ofF=k;0BExBzQcrGh(Z?1A-(Nr9h`I5P!JMEr1d=Zn92YCQ_BN z`G$rxcG7%;)Z_c8pG}#|OQ<0d)r#iEa6?+8XrDSIg?b*bEZM@v;*xJm^^ME!iAfk) z4v`2+n>U;*I67aXw^H%GzgF#gFr*xn4w|{*r%giw3EM_d 28-TMH%mb! zI1@}EsbR8o1fSazS?`ueojA=FwWavF0nOG}K#!aLtJ9^b^jkN=G_Q+^A9|-z1ePM5 z_18!*on`a!a1l;>O`C1l#MtR`wCG{a@@7xqfyOP<#Y_yuw3+AJE!f;_>N(jdwj?jI zWCq+SrGH|#-o~v;O!ex7RVusz6xxRoiKU{Tb()hH`)o>x!q<7G4?0} (gN>&S4}Q&qf7x+fMZ z)>C(3QOac18 d2B7cvRZ^cqm|Z=>3@XAIG5H=nYjJD_|-BUkl)X1g%8`e z`ddcxahba-1R*fGkiU@$=pm8A3KX1hjdB>Ts-i y_ zd!fm{T$AGLIrhM09fP%`sfU_?Z~a4`DAO=r5xIwP?Sz#6?sBQ)Gs`-}Y_fcQ%zCVH zGJnratZ8Bg{HHKkLacRRi}t8rZHK=A=^2W8W!mVZO6u PWomzSQr&kpFVm;01F=`2=%gta_Cs(78M#gIfkJ$}7dI z+4)0{Cw>SSMv`vO>o%ZR=pxPfSpmbmEPuw;)2yuNNMNilu1ra^=%7C?aA^|{&q!H5 zD7e2_ijVrAdfyH~_?R=BH`8Yi)_R}e5sG)gP Hk2X(gtSCI&R? zvXVZ!-;|!_-DUZ1vSKk|l=xHa^0*=oJhp~VsxawgvCfWeg|^`i5zMY4sa }0^bVH- ziW2 A-h6n!cPyWO2Y+@SQMqVZ2Kj%n&V1iX%oi1>M++y0*{{If;u#}9`+ixc zFHUKC=1+lv4Z;6rx5u!O&WT?A{W~Hes;?^`KfFRZNl(7hbZ~fOz@(JA{0m2gFS0h> zZIKxh(x69+k?)mhta6f?&aBHeUV;NdLY*0wMKF*D)3*LN3aPr$Hh(w53cRgGco!F& z1NiUqMGpBIlqHP;_N5*0$6bIsS(?p5d*It$fV &;69=n$*E#N~l F8Y)8JuRPqA2j6J{#Hp@x$o>T1R%WFw5X+nvmF# z1p@@lbiopT3BrsH4}abq-kmyfF0Ve^&X@S2)M<>NrZ+5xS|CUAv&H-DITuP5UUR`z zto_iz)TC%TE!+NzAyqC0KTIT^b`7vD6A3j1476Fgsu*gEeYIeL78|=50nR#YH{mej z!v?r!o{BgyoyAR7PfkC)wwd|65uHpP42%5_het=&XplZ=Kz|>G?1Q2+Iy*UjYZVnK zkQzIQ?>;nAulLRlEmzO)vq>#6x({6;=U%gb!N2}$Lsh`SZiv37;ja#8UVr_^$eoSB z?X(qxiHDm+sv8>EhScHQb%zzm5~8yENGppqCjUo2W~omD|Nc;^K xO!M*;W z3cS0VaYbyduYXV_(WaK2fQD|6c`)osNQIEuG@z3`Em7HdeE>~pMQOQnWWN2v4wZ22 zb*#wdjdBRpEW8b>HLXg>oFc@0u;OWR8h4dkjj6i66ZpT^Db|*W+w73I`ob&+rn1tF zTLL-rL*=T5i<6RsUh09)e2?a5a NW_>8Vj)MVSfx22y|QXC7ph+NI7EJvFHOd z 8Vj(EvCS! z?i|BD&f$yTlWTfcRw(xc^jMOGsa;JXQVEE=tW0RTY(UdCx4{@ol;PJS7eN%lQEV=# z^7(&|^M9SRa{&oDN^O8K@(7dkdWnVsT ;)(Kj`w4lnvqPS3lC3SxI8|#`BLUu&cYib( 0wJBp zAaeQX 8-OSfrPISi-*h`8r%f%=wy7naE;uzY| z(^glzBrv`+67)TP3!ws5cxx{sLN%!uPj()Y#~WMvZip4j4#3mvDE=r52^jtTG!6); z&VRF+KS{rH1K<6~7R2UReuvwdSxYM0Zb}^LdlkD2O`R}oFDlY5AESWOumy7uI(6$Y z*?vy8 +tX9M(=ZH zn9@lF4P&Y)%gZ>ZT3YA%{shJq@_lDx8Mar8(IstK6qz}Jr) xv43TjjPPrm)hlYk}QleK&F l zf~}{FqEB0NZ&g_!DYwDQhPuW~fwDE_n(yw^l|gi%Zc~~ x(tlGh#c;E^HqK$X1-(<4#Q>zM(P{!E)A8AJvrFCtM-$AcWwqH8Z_X>=8&|J} z?_#<1sQ|V4V(b0YlDo3#tt>c84=_`N71Y?chAadtue>#jBEz2G`aQ*4?mY|)A zI`W$l&BR&FL39dyO_@A-2Y 5{2=b2ufEZ~*8q%2Cf zvZO9-)+qXPhY|zfZ6^&PW+>E}qh3Sr>5~!+2?82Tp-FxVtjP*$2hua ZI ym&X}B?bMvDJ61mvr!OA 6pqN7`pP|m478&KJ9*9lbXW=ui+hDPNcoK#tm>gHBWt>+XBZ+mMN!hj_CxiS3^1p zA|UXxIA2Rg?c#v0ihI|fxfnD*DXNJATZ7_=ETfM9!vB|--@klxy_>SXG5fn YduL85P0vk|E0|XQR000O8wSt>esqylL;&T819&`Wz7?T~98-I+tbx<77 z^FNHc6D+s~3GPmCcXx;2?(R--zXW$efMAEa9WFr+cXv48$NTfGdj5W v)et> zwbR`*)k@-;isIiWxLMdJl*Bc^TH85TF;l2In0Z(`yEzI_$S5l7it}(WQ%Ja3nR!@Q zQaC#aP-uEuQ7D=DQgHB5uzzz2uyF}+@=|cHad1)m|11|wQ2$q;<&-c#$jQg;lfPqO zYHDk0W@-vMOCmNg00mv6DngC353{`sSqp;z=Ygr_*#h_o$`wE?tZ2V>tFkQoQjS)F zy)1k&JZNZgEN?c7Q|yR1&OSSQ1QVNgQ!Epx7 |pKk2SI^o?7v={$RAkGMgN`9IITapc}fcMOsXHz zCISvdPnMER@^F)ONM6TXyR AWq*it%HmrJIoP^YiPrveJDL9F6a|Enw(I+^xJD++T;D$|8~hR8pq}^~ z52Xnq5I*n*=>ix^pOfO$=L=U)HZ6MysS5Xp-ZEx$$=S4U%C#9FbSroejdz*)+zMYp zXudcjhebvdU!G#N=H7B|n2j8G4$A?TsU)bJVgMzt@qe``2^5cXQN$^7J|CPF8!*%% zK0;+OpKwqDx&1Sb-U}^ukV*zHzz0$zUC71`n+I3b-W4)|B@enqJB!(mz*2 vz<`U#GaW2`9zmFpwxJ7Od{9=6>t4BFYB#u%he#46h zE`No2r$qG+w8IL}!J6Q}nA^?!o}$d!w|pQt2=29dIgm;5)*D;#gNz*sXsiR6`I50g z77?8FgV?=4=l^Z1Uqi?0QXpf>rgV$NJ6NTjvi*^;(5pi*28@UhcP2Z&>PZMJ{>B(h z3;PQV$Bf^Dil%u*D=$CcCC^XuN%H7!UVnbZc9FO{FXo+YdoyYqGE5Odk?yNax4ykR zf}it1`&tz1l8Y4m93&FJ^|>l|LGSyILC|boFx6&RrL(3+X8vkJhk;_6nuDN{Tj1tP z&w7S{@7t#<5#bbX%o`S+>%Mg qc+D@~hM1YDI^`n}6HqD?lBX_uz*kBolkX4ZiTsXe v~Si?Q%^&oJ}u z=J6`}2gh&O+8ZA=`{~u9oX2t}ydVuS#44ZD%iGR8a+^$E1IsqO_;-=*?tfsYU^3Le z5<81`tf2Y3*jkZ}#7AcpFo52>DCUxRQpE}WXwDJgNH9)FEgGw_(qh=0e5P Wu24HP|xDTOm5%v%O4dyP4$ zQv2;-xCrC#({ss G`>CF|^Stz@4S7dAWKF72 zIGil#hMIK;o}N(Y^)Qql-&o}&)M@d)xzXL9T7SMs*dgMb{t{!6EPTIgk^BmKnfHt< z!1 x?FkTIh%nAdl>xu()5V}nO+s7-lvfQUMX*3Z >EBT9-D&E?ugd!bbxVB{ju;#fUqgg3z*hrTGcLXOiGZWfpEr>#}|B{Hut zCMUjTGmU7s%qla*$2)j Ws~^=*`rM*n240swqF~u?qj#AG%Dgs$ zoB5gKN|(Ex{v<&&Z7lASoIMW{eL9;R<8hx!>2+G1OKs`ObKkw{p8CVap;%rBJP{B_ zbHBgvsQ~2Gdsjzqsyp6agaVPlMle35EW{xA5P$byVHyjKw!Jyfe4KbBS#L*So8C;_ z 277$rRs-X`jYVrF~CP5z`chRcJf)(w(z=b$r*S- zzPo||Fh)=JoIo3>jQ0=M&(xAV;cveD(dYLn_86=XmxNcPPT^b(G~Xf1(DJAEzn9(c z5PxU;$8p_pw0rFsEFamXGg<~KH?Zd-=g=2oDjf9D0L37>hCh 1ljEAPJxU4EQY1v>K6~4U}DsVT_<2awg-3kJqW5}E|Hl9QVV<&P< zM8v0RK_Lg8qPcAPbZ=GmpEMvN48P3WGp*oLIBEzLn1NJ1YA4AA+$OZS3 $ z&V+Ylm*ox;$y^Yf3vxFKUUf%U^?x7OhED2-)oFP&@^m(Eakz0Q-JAG>yzXf?l(I(q zt@$Soiy`FxGq?@G2jvp+@Ur4!*0}|0<7 ^xy#X22!SsdTKQkvum~9;!HijsPv%_) _rwt`hskRlV0M}Zlbt b6w*}!)+C;Mw16NR*g5|@G$&ps)_ zYDe_bQ%47 1&C6yKlCktC2he*$7A!@Qs z{lg2BLJZxFLo5nhJuU%K!(NaM_#<9ngvGdk->j7eL~d5}!%eFc+L?&FVl0pYuFNq?6e7{G#vBHYVDZW>$#W28)MNN2i6il`EC0m!t?{x#CgKFi`l zf+J3AnBlV6TWU6uT%lLP*)kKfP7^UGF)A4{{xl`8ydEPlBnpE8MZq`H+J7GS2ZAxK zZ0_IILvShck+y)QYM&$pG##lbw{fUe7TSCyh0oOoy*$5&Dt}S=2F*0conQxWh!d(* zz37kAU7F@bB!0ir_gu$B=gYzdS)F$GdbDX>-!S%dtYlA4t)-iG*)Ivif-cZol_FO2 zqnSFwDezguFe~Www3ig`4Zl4q&^~(JngnvkYKjkxa0w|lKgqv(qhHlzTtW(rv#+{% zFSU;} 6nW?&r+W& 7>2DE3=Gk>lXC=A($gV@W-;%Bwf&|P^L zxGEPjgOrlmK2Lu7Jex#IAb}%&8iUwClga>3E?b>3xkcA)C@H|2`2>ILyq~3m0AzIk z+m#EaZi-Yr^K3QpY>GHrj;xje%!rWzZ9#9+DortwYxj1UeY$NI5w_E_^!<0cLq@E| z<~e^RL4Q-Bt?$yjv5Dr_A?xg&WE_~`Dws3jgmpzpU|M@OD605!MUG(P{G+brT{BA# z =!Bj1X#*HplH|J^w;;4=B5-Fo=1_-(F&W$Zy>F z>OFG5jD5qC#_axA62~#pNM88BKleh88UMHDjw@Dj_?ZC3Q5n^Pje60Ypxuu 4Od| zh%@2_ZR?hb@wr%dMd6{5hlrik@`p#1A^&U7Lz_rM==R!Q{J^Xw$2pM~ky-cdflXg0 z`ak&+UPZTm8C1{^HtBP=4hsy*wf*1hdViimTtp~H2pgj)c=n&A21-0SDZi)JO4JD< z2+rZt{F+WwWwl+HV_L+8@sJyQd47?(6iQd~$+>WBl*vtPlA_S=B@e2}wr@Ud!-tt_ z_KF<;1i`1%9+U?Si+BYWsf 9oY5_0z3+ze=6@xv1i$o^r&fWD$|aeW{s&+v-)VbO8nT-Bk8fPR z@P;rGUObbR-PX8z_i6({4t<8Pu4@~j*L>c^1ct!>=N8uVRQ`*-O=$F`VDK UvvgWL0%xN|ArzVM) QwiTLhzJb#9Q7eNLW zD_`(onE5*zI=eUXcrUtDT2gnI0$Gl3(nVTkRowGc-dj*)Ot5$eMQH;s1!>So?a_je zzO_?VtwCeLRC%TUbeL}-RR~FdoVuwbwW)fwEIdnFL_I?U_Job7h68CnuIPO)a$jm6 z6x>S-*EJ(P)kS@2lxJ(!SAUQ!6vM>>9?%B+LT|vnjyT^H9;6iE-Y6L~)+bvn6>F=C z1@viN9eb?0U62Y`#}PrO(gDR@>;jdJPJY51Q1eo(0K9rk#+8^DKq#lr@B7bH-sGa%3Z`Cwe zpH+k1N`scao({9(1!Q4w?%{O7X(_kGJ(4T1RwLOoOM(bK-Iq5UN6RvR)?^ZH1E-7Z znL?dd9*p4uiI1l^U8EeL@LY*kLdk?>L^vivSW{X9?w*uWsEkL JLD#9Im%O~uVvum?K z)a?xz>Ec95Qh@oLvDp}?Cmk>z!`di?{9U0q4`#Sk6KLUi>qfQ(ka_$$*_M>Ag9Xaq zciV4Ze@LHVzu (jiGbw4S-( zdC$#V<8kUZ-8h55-&DxPaTY#V%3t>blYKU+jWr&uChQka_#6kLT9}~nmo0e$KbJL7 z>jk^{hL26tM}G@~`^7?a-0TY)k&zr-VZU@#uQIBfc-$9N^5@%0{l nL NMGMH1la?e?65uc7>b8v+i9N)@zb<>8j*34j+b?3GX4fC7 z8Am88{#bwJ+F6&onQrP%=^V%d2J|Al15hAPTZl-av47>L#I+&`qY-X1#FsIZe;qr0 zHJ Q@pz@zgg}K$UV5~>6{DQdT7=IkWU6M<9rylxrcH%%X3`Zcb)_YV73{1 z_(eKag@4f~6~sorcA7OL{F=&;%j6U0p4G|RE3aJh3M3=AYOU4t7m6}Ut<3%NLR3gF zkZc;LxQqmxgjN` IeieW>y>hVGWqv`xOFVt;e`jJ226g_qjP!~vr~CJ!HKRp?7g zoG9pz$LG1v4HJ_kwN8V9*rT~Z(wtjB4KWD4!QTQ(@wKxN*~uhSJQW#89X%Dd#ymZh zD+$C!uw<-uXd;&UwHQ@ZEsH9+w=kuMiB($s<3NxoF8Zn%ekfe^0BJH=tJ58(ZAwz0 zJ%5pf7}f7b`CBv_IKR0=ZyAfV9zn{zfVPa?>r#B)*hz}3rDQu~BOZ^1-iA(#%8og! z EewHYUTFX1f1;ZVl?Y2ap?QE>2ZLEl6ENst;v)l~FLuMyl?S~u- zfi8f`qu*Y|n|~!@%tJ4UaewN-;^11f%zwJ{>F3p*O*|j6zMFmUU{H1xRAcHaR*Gb( zhb|swa>Jd9_yCi&* zX3sermJ{}0EZ|~y-;J5|;Ht?kQ0w2*=RN}iOLD#Zvc;Cge74luosyfGQ#O6{M}N3Q zYDy3D)ja{hcg+9n_=Mh!(}x{5sw$HVp-`uec!q*CYv5gJRjY bEstD8=R0&jaxhOnz~?T6DuV3qX1Z0A=j*f^;_Q;ZE5 zCZF;BLS6qM X8ZYx1*~19#GO=TMxryrSGS+g?|&;D=(5VF=at$0 zB^z*neJ<4JN$uAY9xkm`fHzqkOyrV;1;Xxw#%!5A`fA$4Xqt-r4<)?EyC~b4qYZY7 z3c2+A$rW4XSIXknuP1W;`(8OwvL=>!G=b^&k_8?WtjngIO!kltgnZhF#t0W6#wc;_ zTx?+X0tVlb(67+)P=BA#F*X%nYu#M_Hh;CF$(WG%thR}mLGR>E!Zg_w_s|ylfUw=k z9?M&NgjX;UKVXKjHMIxMVi%oXaEy*TkWuSUyxGCpBFWw1G2~1hS06Bb10JWQNWJRP zl@?a$-38QEO8;!mKB4_9OV$x}+GU;KU#!`k>*0&KwKmpUnSbg?CztHDWb@nHQ+I%( zmSFBxDI%B?(S+aN>1VSH^<~JjUVE3Km$3}r68-YOq~c6^y>w~D&atLBO%n%-{KPe% z_43qj3q7+%R57#_* nW-nSbm$s*OxswWcV?PBGN=(@qZ zY#{Oaz3nPAp+o~CJ*e0+eT#i?>%-O*9Aq^xnlUpLBX)w`?ZN)hj~hy0!7^zz?BA|i zKLFp8SyeZxtvLqOe#{F`0?jE&m~=27a;9h|7RVH+(tniKzdd uI~!9w>z^h((WYyvv62Z+EWbLYnSe zw%9T@UmSqtU#Lh=jx+bF)Q4n~^@8i5;U?t@HuNc`eDu2eX}wAOJv~XG_~C1zn}`Py zwVWV+$A3c8SbEcrJbmU_cRp2qCa(?MMgBvp2zR2bLwC52)4*H16J0##k%qkAZ2g%d z%B1D1S*5EiaHFs6QSEf-TDbB(UB6Y*RYc}*j)9)0d0nRe!lfc_R@+7o;s9DAK=;8v z+YR ~A)(edAYI(RX z314KenmtY=&?Yq*JXj!~uYjPf8Iw Fh4^E}KT{py zF6W9(oa+woW^PfXi6H3`wJ%dO)LnO@0a#n%6f4eqm*#;9_rzBDQ{Uet)sdeb%Q&f< zw|`&q?Uw3;30({$cBt|%1PU?T=}Z1RNIVPEXC7y~#y1~|{Z;7#l{`165pbXA_>^Wc z3U`jevc57GuU85rg1A*W>b@Ck?x#>!)Wz?X^CDd+DX*#Ao}oxrfdZPjhPn;VRiZqp zbt%%4E5^1zHw6qBEwjnIL;s(BUw6Wl`G3UYDBk%q1V!BdWx);GA-t0hDHa7amdk6c zqQL^2zA9qcdYja_?9{~Dx}XFvX51LRFihr%`qtIYIvC>q2gK~7Wkt)>v2*t@`2@;w z2Pu;5)F@2*5Xv*E+^asW#|F)?!J97k?ED zSA`6hb(BDRA|D(ZlTZx_zGk%ikn3su_R9q9M!UU8m4RP$&L&}3E_nQ#7Vyf%TTPrU zF&8HtdBhVauvHH+63ykGA7J<6)JlPU&Fzb;`g4Uc+Mxucv_B}NR%Ud-Yv1@ QIim|y|A`Lm0wtetC&xeiC1r3Y=a#kmm(@d zvsXev=M--kf5Q2@2#_Y5V}n!-La| <3_KLi_*GO~i3tc^UaH*>FM{zP B1FSlft-O}k2sl){XS%Ok zGxJT?A;<=qk#5oLTokhmDTcdQhDlyqI&A!{1vJGu1eB~wn;AWygiL8Fmm+Dj;bWAR zO2QC80nlTOh0YW&P82V*D}QOvCpj<|9DN-Lm)Ap^juGy}TL}*4t~uSk^S>$-uW##7 z*6<=aQX{ML5?*-t+4<5y8Q=G7VSUd`{uXY@UVht(riv5V?<>GYg_RQ{bVI+?chGM( z70f(ywzk*%akHWWK17n4nqImZ@(@OY(H()USAjW>`|6A|KI>i_@_!<_)c=4aBhs?{ zW&IZqDa!Z4u@RhyVb0?Vo6?)C u1>U;0)<>}D>7^gu$6fml}e z5{MsE%kz-6&4aH&*$mf=cDd)1#&h!